From Marten.Terpstra at ripe.net Tue Nov 1 18:25:49 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Tue, 01 Nov 1994 18:25:49 +0100 Subject: Indexing problems In-Reply-To: Your message of Thu, 27 Oct 1994 17:31:33 -0400. <199410272131.RAA10116@merit.edu> Message-ID: <9411011725.AA09703@rijp.ripe.net> Sigh, I am not sure I like dbm ... ;-) I found a cure I think. Up till now I went to my escape mechanism for large buckets whenever the current bucketsize and whatever I wanted to add exceeded 1000 chars (because I assumed the bucket max to be 1024). Then I suddenly noticed that the funny dbm bevaiour happened when the old bucket and to be added value was *exactly* 1000 chars. I changed my test to 950 chars and voila it worked .... Could the MERIT folks please change the following and see if they can index the prdb? in cldb.pl routine setmspnxl() change: if (length($value) + length($addvalue) > 1000) { to if (length($value) + length($addvalue) > 950) { install and run an index. It worked for me on prdb .... -MT -------- Logged at Tue Nov 1 20:47:54 MET 1994 --------- From Tony.Bates at ripe.net Tue Nov 1 20:47:44 1994 From: Tony.Bates at ripe.net (Tony Bates) Date: Tue, 01 Nov 1994 20:47:44 +0100 Subject: Indexing problems In-Reply-To: Your message of Tue, 01 Nov 1994 18:25:49 MET. <9411011725.AA09703@rijp.ripe.net> Message-ID: <9411011947.AA28000@mature.ripe.net> Okay, to fill you in on the testin with gdbm. I tested this today. What I did was build a version of perl using the gdbm libraires. The basic results are that it indexed fine and the size of the dbm files were nice and small. Slightly smaller than the actual database. There were no problems whatsoever. However, here is the downside.... The index itself took almost three times as long to build. I currently do not have more time to do any real testing at the moment but this does highlight a basic bug in the standard SUN dbm somewhere. For now we will go with Martens workaround and if MErit folks have more time to spend looking at the pros and cons of other dbm implementations we'd be very interested. --Tony. Marten Terpstra writes: * * Sigh, I am not sure I like dbm ... ;-) I found a cure I think. Up till * now I went to my escape mechanism for large buckets whenever the * current bucketsize and whatever I wanted to add exceeded 1000 chars * (because I assumed the bucket max to be 1024). Then I suddenly noticed * that the funny dbm bevaiour happened when the old bucket and to be * added value was *exactly* 1000 chars. I changed my test to 950 chars * and voila it worked .... * * Could the MERIT folks please change the following and see if they can * index the prdb? * * in cldb.pl routine setmspnxl() change: * * if (length($value) + length($addvalue) > 1000) { * * to * * if (length($value) + length($addvalue) > 950) { * * * install and run an index. It worked for me on prdb .... * * -MT -------- Logged at Wed Nov 2 11:36:20 MET 1994 --------- From Marten.Terpstra at ripe.net Wed Nov 2 11:36:18 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Wed, 02 Nov 1994 11:36:18 +0100 Subject: Bug in classless indexing Message-ID: <9411021036.AA10685@rijp.ripe.net> folks, I have found a bug in the classless indexing when doing complicated deletes. The classless index gets sort of confused at times. I have not yet found under what circumstances or what really goes wrong, but I'll look into it asap. -Marten -------- Logged at Wed Nov 2 15:14:20 MET 1994 --------- From dsj at merit.edu Wed Nov 2 15:14:16 1994 From: dsj at merit.edu (Dale S. Johnson) Date: Wed, 2 Nov 1994 09:14:16 -0500 Subject: When is T2? Message-ID: <199411021414.JAA14772@merit.edu> Hi, Can you remind me when T2 is (full conversion to Route objects, etc)? We're trying to track this in our code, and need to synchronize with you... --Dale -------- Logged at Wed Nov 2 15:15:36 MET 1994 --------- From Marten.Terpstra at ripe.net Wed Nov 2 15:15:30 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Wed, 02 Nov 1994 15:15:30 +0100 Subject: When is T2? In-Reply-To: Your message of Wed, 02 Nov 1994 09:14:16 EST. <199411021414.JAA14772@merit.edu> Message-ID: <9411021415.AA10871@rijp.ripe.net> "Dale S. Johnson" writes * Hi, * * Can you remind me when T2 is (full conversion to Route objects, etc)? * We're trying to track this in our code, and need to synchronize with you... Currently planned for November 21st. -MT -------- Logged at Wed Nov 2 19:18:33 MET 1994 --------- From Marten.Terpstra at ripe.net Wed Nov 2 19:18:30 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Wed, 02 Nov 1994 19:18:30 +0100 Subject: Major bug fixed in enkeys.pl Message-ID: <9411021818.AA11347@rijp.ripe.net> Folks, please replace your version of enkeys in the RIPE DB software with the one below, it has a major (and I do mean major) bug. It appears when indexing non cidr blocks in the database. Basically the split into cidr blocks does not work ... That is fixed now. -Marten # enkeys - extract keys from entry # # $RCSfile: enkeys.pl,v $ # $Revision: 0.18 $ # $Author: marten $ # $Date: 1994/11/02 18:12:49 $ # require "misc.pl"; require "cldb.pl"; sub enkeys { local(*e) = @_; local(@keys); $type = &entype(*e); foreach (split(/\s+/, $KEYS{$type})) { $value = $e{$_}; if ($value =~ /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/) { @keys = (@keys, &getipkeys($value)); } else { @keys = (@keys, &getalkeys($value)); } } return @keys; } sub getalkeys { local ($value) = @_; local ($i, @result); @result = split(/\s+/, $value); $i = $#result; while ($i >= 0) { $result[$i] =~ tr/A-Z/a-z/; $result[$i] =~ tr/a-z0-9\-,\._'\///cd; #' quote to fool emacs perl mode if (length($result[$i])<2) { splice(@result, "$i", 1); } $i--; } return @result; } sub getipkeys { local($value) = @_; local(@ipkeys) = (); local($counter) = 0; foreach (split(/\n/, $value)) { foreach (&old_to_new($_)) { $ipkeys[$counter++] = $_; } } return @ipkeys; } # # Old routine, before cldb era. # #sub getipkeys { # local ($value) = @_; # local ($i, $inc, @result); # # @result = split(/\s+/, $value); # if ($#result == 0) { # $result[0] = &trailzero($result[0]); # return @result; # } # # local($lo, $hi) = (&quad2int($result[0]), &quad2int($result[2])); # $result[0] = &trailzero($result[0]) . "-" . &trailzero($result[2]); # # $inc = 256 if ($lo < &quad2int("224.0.0.0")); # $inc = 256**2 if ($lo < &quad2int("192.0.0.0")); # $inc = 256**3 if ($lo < &quad2int("128.0.0.0")); # # # for ($i=$lo; $i<=$hi; $i+=$inc) { # @result = (@result, &trailzero(&int2quad($i))); # } # splice(@result,1,2); # return @result; #} 1; -------- Logged at Wed Nov 2 19:48:43 MET 1994 --------- From dsj at merit.edu Wed Nov 2 19:48:39 1994 From: dsj at merit.edu (Dale S. Johnson) Date: Wed, 2 Nov 1994 13:48:39 -0500 Subject: draft "advisory" text Message-ID: <199411021848.NAA07357@merit.edu> Daniel, Tony, Marten, others, Here is a draft description of the new "advisory" attribute for the route object. The text below is split between additions to the current "Experimental Objects" draft, plus a prposed new "advisory-as690" draft. This presentation still feels pretty rough to me, but hopefully this is enough to get us started (since this all needs to be implemented very soon). Comments, flames, etc. welcome. --Dale ============================================================================= proposed for "experimental" ============================================================================= > > > > > > > > > > > Experimental Objects and attributes for the > Routing Registry > > > Laurent Joncheray & Dale Johnson, I suppose. > > DRAFT > > Document ID: ripe-1nn > > > > > > > 1. Introduction > > Two new attributes of the AS object which are proposed and supported > by the Merit Routing Registry are as-transit and db-selector. A new route attribute "advisory" is proposed. > > 2. "as-tranit" > > as-transit describes the transit preferences of an AS. It allows an > AS to describe its path preference in order to reach certain desti- > nations. The AS(s) specified in the path preference may or may not > be an immediate neighbor of the AS defined in the AS object. as- > transit accommodates policy decisions involving AS path whereas as- > in and as-out do not. It is not unusual for ASs to have routing > policies which involve path selection based on AS. Emerging proto- > cols like SDRP will allow an AS to choose a path independent of a > neighboring ASs path choice. as-transit permits descriptions based > on AS path selection. > > 3. "db-selector" > > The DataBase Selector (db-selector) function allows one to take > advantage of information registered in other Registries. It permits > the selection of networks in a database based on their attributes. > It is proposed to be used within the as-in/as-out attribute family > to make the description of policy concise. For example, if an AS > has the policy of not accepting any routes from country XYZ, the AS > can use the db-selector to check a database which has a network and > country attribute and relate that information to the information in > the routing registry. The advantage of referencing another database > is that the routing registry will avoid duplicating the information > maintained in other information registries. > 4. Route object "advisory" attribute The format of the route object advisory attribute is: route: [prefix/length] advisory: ASXXX [AS-specific information] This attribute provides a place where the people responsible forrouting the net can provide specific suggestions to remote ASs on how that remote AS should handle the route. For example, ASX would like to request of ASY that ASY accept this route R through ASY's router Z. To implement this, ASY needs to put an interas-in statement in its own asn object, specifying that route R be accepted with a low metric through router Z. The actual policy representation that is used for routing will be ASY's interas-in object. But ASX's route advisory attribute provides the way of requesting that ASY make this change, and of registering ASX's preference for this particular routing. --------AS690-specific example: delete if you like: As an example, the NSFNET Backbone service (on AS690) has registered a policy in the document ftp.ripe.net:ripe/drafts/advisory-AS690 . This policy allows any registered route to specify its preferences for AS690 interas-in information for that route. The format for this information is the same as the PRDB "Metric:AS" lists. --------end AS690-specific example --------In the text below, I volunteer RIPE to host a set of documentation files. These files might to turn out to be a bit more dynamic than the RIPE-### documents; they might be modified once in a while. I suggest below that they remain as drafts. If someone would prefer any other kind of representation, or some host place other that RIPE, that would be fine with me too. (ftp.ra.net would be ok; in fact I'd like to shadow many RIPE directories there. But as the founder organization I think ftp.ripe.net would be the most appropriate location. Any AS that wishes to accept route advisory information in this way should register a description of its advisory format with the RIPE NCC. Such advisory descriptions will be stored as RIPE drafts on the directory ftp.ripe.net:ripe/drafts, with names of the form advisory-ASxxx. The content of these drafts may change occasionally as needs change. [something here about an appropriate list to notify when they do change?] > > > > > > > ripe-1nn.txt September, 1994 ============================================================================= proposed for ripe/drafts/advisory-AS690: ============================================================================= Advisory-AS690 Use of the Route Object "Advisory" Attribute for AS690 Dale S. Johnson Document ID: advisory-AS690 [November 2, 1994] The RIPE-181 document describes route objects which are used as part of the Global Routing Registry. The RIPE document "Experimental Objects and Attributes for the Routing Registry" describes an additional "advisory" attribute which may be used by those reposnsible for a route to give routing suggestions to other ASs about how to handle their routes. This document describes the syntax and usage of the route object advisory attribute for AS690 and the NSFNET Backbone Service. The syntax of the route object advisory attribute for AS690 is as follows: advisory: AS690 Metric:AS[(NSS)] [Metric:AS[(NSS)] [Metric:AS[(NSS)] ... ]] This attribute may be included in any route object. AS690 will scan the Global Routing Registry for route objects which include this AS690 advisory attribute. Those route objects which do include this attribute will be specifically added to AS690 import configuration lists. Each metric must be a small positive integer (metrics are usually sequential, starting with one). Each AS must be small integer, indicating the AS number of one of AS690's peers which will announce the route to AS690. If an NSS router is specified, it must be the number of an NSS which is peering with the given AS. Questions and comments are welcomed at merit-ie at merit.edu. -------- Logged at Thu Nov 3 12:02:50 MET 1994 --------- From Marten.Terpstra at ripe.net Thu Nov 3 12:02:46 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Thu, 03 Nov 1994 12:02:46 +0100 Subject: More bugs fixed Message-ID: <9411031102.AA12442@rijp.ripe.net> Fixed a bug when deleting objects that are themselves a more specific of something and have a more specific, were treated wrongly. Such deletes would mess up the index, although it would not show in normal whois output... I think .... Please replace your cldb.pl with the one below. -Marten # $RCSfile: cldb.pl,v $ # $Revision: 1.5 $ # $Author: marten $ # $Date: 1994/11/03 10:57:29 $ # This module contains all routines for classless indexing and lookups # and some routines to do conversions here and there require "misc.pl"; require "defines.pl"; require "time.pl"; # This is triple booo!!!! Change this !!!! # $OVERFLOWDIR = "/ncc/nccfs3/cldb/data"; # # convertonormal($cla) # # converts a integer prefix/length internal structure to a readable # quad prefix/len string sub converttonormal { local($cla) = @_; local($int, $len) = split(/\//, $cla); return &int2quad($int)."/$len"; } # # cla2unikey($cla) # # gives back an array of unique keys into the database that match this # cla. Basically it will extract all the "O" values for $mspnxl{$cla} and # put them into an array. sub cla2unikey { local($cla) = @_; local(@result) = (); local($cla2tmp); &getmspnxl($cla, *cla2tmp); while ($cla2tmp =~ s/^O([^,]+)//) { next if $1 =~ /DUMMY/; @result = (@result, $1); } return @result; } # # getmspnxl($index) # # gets the value (a string) for a certain index in the assoc array %mspnxl # because of the overflow mechanism, this could be retrieved from a file # or straight from the DBM file sub getmspnxl { local($index, *value) = @_; if ($previous eq $index) { } else { $previous = $index; } &timer("getmspnxl", 1); $value = $mspnxl{$index}; if ($value eq "ETOOBIG") { $value = ""; local($filename) = &converttonormal($index); $filename =~ s/\//\./g; local($counter) = 0; while (!open(FILE, "$OVERFLOWPREFIX.$filename")) { select(undef, undef, undef, 0.05); $counter++; if ($counter > 10) { die "major failure! cannot open $OVERFLOWPREFIX.$filename: $!"; } } sysread(FILE, $value, 1000000, 0); close(FILE); } &timer("getmspnxl", 0); return *value; } # # setmspnxl($index, $value) # # sets the value for a certain index in assoc array %mspnxl. Because of # the 1K max in DBM, the overflow mechanism must be used for large values # In the overflow mechanism, whenever a file needs to be updated, a new # file will be created, and renamed after. This is make the time the file # is not available (for servers) as short as possible. sub setmspnxl { local($index, *value, *addvalue) = @_; &timer("setmspnxl", 1); if (length($value) + length($addvalue) > 950) { if ($addvalue) { $value .= ",$addvalue"; } local($filename) = &converttonormal($index); $filename =~ s/\//\./g; # unlink("$OVERFLOWDIR/$filename.$CUROBJTYPE"); # Create a new file with new values open(FILE, "+>$OVERFLOWPREFIX.$filename,") || die "cannot open $filename: $!"; syswrite(FILE, $value, length($value), 0); close(FILE); # Move the new file to the original. rename("$OVERFLOWPREFIX.$filename,", "$OVERFLOWPREFIX.$filename"); $mspnxl{$index} = "ETOOBIG"; } else { if ($mspnxl{$index} eq "ETOOBIG") { local($filename) = &converttonormal($index); $filename =~ s/\//\./g; unlink("$OVERFLOWPREFIX.$filename"); } if ($addvalue || $value) { if ($addvalue) { $mspnxl{$index} .= ",$addvalue"; } else { $mspnxl{$index} = $value; } } else { delete $mspnxl{$index}; } } &timer("setmspnxl"); } # # old_to_new($oldnet) # # converts old style RIPE database network numbers (single classful net # and classful ranges) to prefix/length format. Prefix/length is the # internal representation used. Routine to convert a range into # prefix/length is happily stolen from "aggis" by Dale Johnson, MERIT # Thanks Dale ;-) sub old_to_new { local($oldnet) = @_; local($len); local(@returnstring) = (); local($one_net); &timer("old_to_new", 1); # Conventional classful nets if ($oldnet =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/) { if ($1 >= 192) { $len = 24; $len = 32 if $4; $one_net = 0x00000100; } elsif ($1 >= 128) { $len = 16; $one_net = 0x00010000; } else { $len = 8; $one_net = 0x01000000; } } # Special case, it can happen that we got a hostaddress and mask # let's make sure we remove the mask when we return this. # this is for ifaddr in inet-rtr if ($oldnet =~ /(\d+\.\d+\.\d+\.\d+)\s+\d+\.\d+\.\d+\.\d+/) { return "$1/$len"; } if ($oldnet !~ /\-/) { &timer("old_to_new"); return "$oldnet/$len"; } # Now, we have a classful range, let's convert this into pref/len if ($oldnet =~ /^(\d+\.\d+\.\d+\.\d+)\s+\-\s+(\d+\.\d+\.\d+\.\d+)/) { local($begin) = &quad2int($1); local($end) = &quad2int($2); local($newbegin) = $begin; while ($newbegin <= $end) { for ($pwr=1; $pwr<24; $pwr++) { $pwr2 = 2 ** $pwr; $thisend = $newbegin + ($pwr2-1)*$one_net; return @returnstring if !$newbegin; if (($thisend > $end) || $newbegin != ($newbegin & $masks[$len-$pwr])) { $pwr--; $giveback = sprintf("%s/%d", &int2quad($newbegin), $len-$pwr); @returnstring = (@returnstring, $giveback); $newbegin = $newbegin + $one_net * 2**$pwr; last; } } } } &timer("old_to_new"); return @returnstring; } # # findlsps($cla, $recursive) # # Find the list of less specifics for prefix $cla. If the recursion # flag is set, all less specifics (lsps) are returned, otherwise only # the first less specific. It is not a recursive routine, but oh well. sub findlsps { local($cla, $recurse) = @_; local($prefix, $len) = split(/\//, $cla); local($returnlist) = ""; local($ii); for ($ii=$len;$ii>=0;$ii--) { local($newcla) = ($prefix & $masks[$ii]); local($tmp); &getmspnxl("$newcla/$ii", *tmp); if ($tmp) { if ($recurse) { if ($returnlist) { $returnlist .= ",$newcla/$ii"; } else { $returnlist = "$newcla/$ii"; } } else { return "$newcla/$ii"; } } } return $returnlist; } # # findmsps($cla, $orig, $first, $nonrecurse) # # routine to find all more specifics of a certain classless address cla. # Because of recursion, it needs to remember the very first $cla it # is called with, which stays in $orig. This is needed to check whether # all found more specifics really are more specific. By default recursion # is on, it will try and find all more specifics. sub findmsps { local($cla, $orig, $first, $nonrecurse) = @_; local($j); local($msps) = ""; # Look up first less specific when the requested $cla does not # exist itself, and use that to find all more specifics. local($tmp); &getmspnxl($orig, *tmp); # Now, if this $cla does not exist itself, we can do two things, # - we can step one level back, and check all them (painful if # you have to step back to 0/0) # - allow only more specifics of prefixes that are actually # in the database, return nothing if the prefix in the DB # does not exist. # If you have indexed with priming on, the first is no problem. # If you have indexed with priming off, the first may take CPU.... # This implements the first solution # if (!$tmp && $first) { # $cla = (split(/\,/, &findlsps($orig)))[0]; # } # And this the second solution if (!$tmp && $first) { return $msps; } $tmp=""; &getmspnxl($cla, *tmp); foreach (split(/,/, $tmp)) { local($tmp); &getmspnxl($_, *tmp); if ($tmp) { local($p1, $l1) = split(/\//, $_); local($p2, $l2) = split(/\//, $orig); if (($p1 & $masks[$l2]) == ($p2 & $masks[$l2])) { if ($nonrecurse) { $msps .= "$_,"; } else { $msps .= $_ . "," . &findmsps($_, $orig,0,0); } } } } $msps; } # # givemsps($string, $cla) # # Give all more specifics of $cla that can be found in $string. I think this # can also be done by findmsps, but I'll keep it in here for now. Only # needed for insertations right now. Returns a sub-string will all more # specifics of $cla. This is a costly operations, and should only be done # for one-off insertations (like normal updates). Indexing a whole (locked) # file should not use this, the "to be inserted" cla's should be presorted. sub givemsps { local(*string, $cla) = @_; local($returnstring) = ""; # return $returnstring; &timer("givemsps", 1); local($pref, $len) = split(/\//, $cla); foreach (split(/,/, $string)) { next if $_ =~ /^O|^start$/; local($tmppref, $tmplen) = split(/\//, $_); next if $tmplen <= $len; if (($tmppref & $masks[$len]) == $pref) { if ($returnstring) { $returnstring .= ",".$_; } else { $returnstring = $_; } } } &timer("givemsps"); return $returnstring; } # # addtomspnxl($index, $value) # # Adds $value to the current value of $mspnxl{$index}. It is a wrapper # for setmspnxl sub addtomspnxl { local($index, *value) = @_; &timer("addtomspnxl", 1); local($addtotmp); &getmspnxl($index, *addtotmp); if ($addtotmp) { &setmspnxl($index, *addtotmp, *value); } else { &setmspnxl($index, *value); } &timer("addtomspnxl"); } # # deletefrommspnxl($index,$value) # # Deletes $value from the current value of $mspnxl{$index}. Basically # another wrapper for setmspnxl sub deletefrommspnxl { local($index, *value) = @_; local($j); local($deletetmp); &getmspnxl($index, *deletetmp); foreach $j (split(/,/, $value)) { if ($deletetmp =~ s/^$j$//g) {} elsif ($deletetmp =~ s/^$j,//g) {} elsif ($deletetmp =~ s/,$j,/,/g) {} elsif ($deletetmp =~ s/,$j$//g) {} } &setmspnxl($index, *deletetmp); } # # inscla($cla, $offset) # # Insert classless address $cla, which has an offset in the database # of $offset, into the tree structure # ! New version that does not store offsets but references to unique # ! keys, which makes the lookup indirect, but makes the classless # ! index independent of the offsets and thus the clean # # Extra flag mspscheck says whether or not a check should be made # for existing more specifics. When using netdbm, they are presorted # and do not have to be msp-checked. For normal insertions, they # should be checked. The reason this is optional is because givemsps # can be quite costly in time.... sub inscla { # local($cla, $offset, $mspscheck) = @_; local($cla, $uniquekey, $mspscheck) = @_; local($j); local($p); if (!$mspnxl{"0/0"}) { $mspnxl{"0/0"} = "start"; } print STDERR "inscla($cla) called\n" if $debug; local($prefix, $len) = split(/\//, $cla); for ($p=$len;$p>=0;$p--) { local($newcla) = ($prefix & $masks[$p]); local($tmp2); &getmspnxl("$newcla/$p", *tmp2); if ($tmp2) { local($tmp); &getmspnxl($cla, *tmp); if (!$tmp) { local($tmp4) = "O$uniquekey"; &setmspnxl($cla, *tmp4); &addtomspnxl("$newcla/$p", *cla); } else { local($tmp) = "O$uniquekey,$tmp"; &setmspnxl($cla, *tmp); } if ($mspscheck) { local($msps) = &givemsps(*tmp2, $cla); &addtomspnxl($cla, *msps); &deletefrommspnxl("$newcla/$p", *msps); } $p=0; } } } # # delcla($cla) # # Delete a classless address from the internal tree structure sub delcla { local($cla) = @_; &timer("delcla",1); local($q); local($prefix, $len) = split(/\//, $cla); for ($q=$len-1;$q>=0;$q--) { local($newcla) = ($prefix & $masks[$q]); local($tmp2); &getmspnxl("$newcla/$q", *tmp2); if ($tmp2) { &deletefrommspnxl("$newcla/$q", *cla); local($tmp); &getmspnxl($cla, *tmp); if ($tmp) { local($nothing); $tmp =~ s/^[^,]+[,]*//; &addtomspnxl("$newcla/$q", *tmp) if ($tmp ne ""); &setmspnxl($cla, *nothing, *nothing); } $q = 0; } } &timer("delcla"); } -------- Logged at Thu Nov 3 16:34:19 MET 1994 --------- From dsj at merit.edu Thu Nov 3 16:34:14 1994 From: dsj at merit.edu (Dale S. Johnson) Date: Thu, 3 Nov 1994 10:34:14 -0500 Subject: `Sassy' traceroute references GRR! Message-ID: <199411031534.KAA01864@merit.edu> FYI: :-) > From bmanning at ISI.EDU Thu Nov 3 10:13:03 1994 > Subject: Too Many Cooks???? > Date: Thu, 3 Nov 1994 07:11:56 -0800 (PST) > > > Hey, Dale! > > Hows this... > > merlin# ./traceroute > Usage: traceroute [-danruvAMOQ] [-w wait] [-m max_ttl] [-p port#] [-q nqueries] [-t tos] [-s src_addr] [-g router] host [data size] > -a: Abort after 10 consecutive drops > -d: Socket level debugging > -g: Use this gateway as an intermediate hop (uses LSRR) > -m: Set maximum TTL (default 30) > -n: Report IP addresses only (not hostnames) > -p: Use an alternate UDP port > -q: Set the number of queries at each TTL (default 3) > -r: Set Dont Route option > -s: Set your source address > -t: Set the IP TOS field (default 0) > -u: Use microsecond timestamps > -v: Verbose > -w: Set timeout for replies (default 5 sec) > -A: Report AS# at each hop (from GRR) (Not implemented) > -M: Do RFC1191 path MTU discovery > -O: Report owner at each hop (from DNS) > -Q: Report delay statistics at each hop (min/avg+-stddev/max) (ms) > merlin# > > > Note the hook for the GRR (sassy!) > > > --bill -------- Logged at Fri Nov 4 18:36:12 MET 1994 --------- From Marten.Terpstra at ripe.net Fri Nov 4 18:36:03 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Fri, 04 Nov 1994 18:36:03 +0100 Subject: Groups running RIPE-181 In-Reply-To: Your message of Tue, 25 Oct 1994 17:03:29 -0400. <199410252103.RAA04998@merit.edu> Message-ID: <9411041736.AA15468@rijp.ripe.net> [Dale lists folks who plan to do or are doing RIPE-181] * 1) Wow! Indeed.... * 2) There is really some work to be done to integrate these various stream * s * of data. There is probably also some work to do to handle cross-DB checking * ["sorry; that net has been registered in the MCI database"] and object * reference ["NSFAUP" community is defined only in RADB, but available * in all the DBs]. Can we pick an evening at the upcoming IETF and brainstorm about the distribution issue? -Marten -------- Logged at Fri Nov 4 21:06:14 MET 1994 --------- From Tony.Bates at ripe.net Fri Nov 4 21:06:05 1994 From: Tony.Bates at ripe.net (Tony Bates) Date: Fri, 04 Nov 1994 21:06:05 +0100 Subject: Groups running RIPE-181 In-Reply-To: Your message of Fri, 04 Nov 1994 18:36:03 MET. <9411041736.AA15468@rijp.ripe.net> Message-ID: <9411042006.AA06558@mature.ripe.net> Agreed, we need to start the ball rolling on the GRR as soon as we can. I would suggest a bof at the IETF although I think we may just want the players. My thoughts on this are mainly the rr-impl group and any others who come to mind / we feel would be useful. APNIC people are ones and some of the larger NSPs who have expressed interest. CA*NET, ALTERNET, etc... Looking quickly at the IETF agenda. I would say go for Monday evening if this is possible. ? --Tony. Marten Terpstra writes: * * [Dale lists folks who plan to do or are doing RIPE-181] * * * 1) Wow! * * Indeed.... * * * 2) There is really some work to be done to integrate these various st * ream * * s * * of data. There is probably also some work to do to handle cross-DB chec * king * * ["sorry; that net has been registered in the MCI database"] and object * * reference ["NSFAUP" community is defined only in RADB, but available * * in all the DBs]. * * Can we pick an evening at the upcoming IETF and brainstorm about * the distribution issue? * * -Marten -------- Logged at Fri Nov 4 21:17:31 MET 1994 --------- From eric at enfm.utcc.utoronto.ca Fri Nov 4 21:17:15 1994 From: eric at enfm.utcc.utoronto.ca (Eric M. Carroll) Date: Fri, 4 Nov 1994 15:17:15 -0500 Subject: Groups running RIPE-181 In-Reply-To: Tony.Bates's message of "Fri, 04 Nov 1994 15:06:05 -0500". <9411042006.AA06558@mature.ripe.net> Message-ID: <94Nov4.151718est.607523@enfm.utcc.utoronto.ca> > APNIC people > are ones and some of the larger NSPs who have expressed interest. > CA*NET, ALTERNET, etc... I am keenly interested. However, I am not funded to attended IETF. Please post any notes/results. Thanks, Eric Carroll University of Toronto Network & Operations Services External Networking Facilities Management -------- Logged at Mon Nov 7 15:35:44 MET 1994 --------- From dsj at merit.edu Mon Nov 7 15:35:23 1994 From: dsj at merit.edu (Dale S. Johnson) Date: Mon, 7 Nov 1994 09:35:23 -0500 Subject: Groups running RIPE-181 Message-ID: <199411071435.JAA07608@merit.edu> Great! Monday evening is fine with me. :-) --Dale > Agreed, > we need to start the ball rolling on the GRR as soon as we > can. I would suggest a bof at the IETF although I think we may just > want the players. My thoughts on this are mainly the rr-impl group and > any others who come to mind / we feel would be useful. APNIC people > are ones and some of the larger NSPs who have expressed interest. > CA*NET, ALTERNET, etc... > > Looking quickly at the IETF agenda. I would say go for Monday evening > if this is possible. ? > > --Tony. > > Marten Terpstra writes: > * > * [Dale lists folks who plan to do or are doing RIPE-181] > * > * * 1) Wow! > * > * Indeed.... > * > * * 2) There is really some work to be done to integrate these various st > * ream > * * s > * * of data. There is probably also some work to do to handle cross-DB chec > * king > * * ["sorry; that net has been registered in the MCI database"] and object > * * reference ["NSFAUP" community is defined only in RADB, but available > * * in all the DBs]. > * > * Can we pick an evening at the upcoming IETF and brainstorm about > * the distribution issue? > * > * -Marten > -------- Logged at Mon Nov 7 20:48:02 MET 1994 --------- From dsj at merit.edu Mon Nov 7 20:47:58 1994 From: dsj at merit.edu (Dale S. Johnson) Date: Mon, 7 Nov 1994 14:47:58 -0500 Subject: AS690 policy with interas-in in 181 Message-ID: <199411071947.OAA15369@merit.edu> FYI: I've added interas-in lines to the AS690 aut-num object. Those who are interested can get a sneak preview with the command: whois -h toad.merit.edu ' -s TESTRR as69' (69, not 690, for testing) Here is a breakdown by count of lines: > % awk '{print $1}' < rr690.out | sort | uniq -c | sort -rn > 522 interas-in: > 342 as-in: > 127 as-out: > 4 descr: > 1 tech-c: > 1 source: > 1 remarks: > 1 guardian: > 1 changed: > 1 aut-num: > 1 aut-name: > 1 admin-c: --Dale -------- Logged at Tue Nov 8 21:04:11 MET 1994 --------- From dsj at merit.edu Tue Nov 8 21:04:05 1994 From: dsj at merit.edu (Dale S. Johnson) Date: Tue, 8 Nov 1994 15:04:05 -0500 Subject: "Advisory" internal attribute name Message-ID: <199411082004.PAA05857@merit.edu> Marten, Tony, Could one of you officially issue an internal name for the new experimental "advisory" attribute (so we can code to that standard)? Thanks, --Dale -------- Logged at Wed Nov 9 18:43:27 MET 1994 --------- From Marten.Terpstra at ripe.net Wed Nov 9 18:36:31 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Wed, 09 Nov 1994 18:36:31 +0100 Subject: Change in config Message-ID: <9411091736.AA21795@rijp.ripe.net> Folks, I suggest you make a change in your config is you are using sendmail to send ack and notification mails. The reason is sort of explained below, which is the bit from our config ... -Marten # MAILCMD is the command into which a composed e-mail is given as standard # input, to be send as mail. The message piped into this command has ALL # the necessary mail header to process the mail: # From: # To: # Subject: # The mail command should take the recipients from the actual message. # Using sendmail it will be executed as: /usr/lib/sendmail -t < "messagefile" # (default: /usr/lib/sendmail -t) # # NOTE: # -fripe-dbm makes ripe-dbm the trusted user that will appear on the # envelope. Bounces will go to this address. If you do not specify # this, sendmail will send bounces straight back to the automatic # mailbox, where it will bounce again, and again, .... # User has to be a trusted user, T in sendmail.cf. MAILCMD /usr/lib/sendmail -fripe-dbm -t -------- Logged at Fri Nov 11 23:36:54 MET 1994 --------- From Marten.Terpstra at ripe.net Fri Nov 11 23:36:45 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Fri, 11 Nov 1994 23:36:45 +0100 Subject: "advisory" and "as-transit" attribute designators In-Reply-To: Your message of Fri, 11 Nov 1994 14:20:24 EST. <199411111920.OAA29118@merit.edu> Message-ID: <9411112236.AA16969@ncc.ripe.net> * * Could you allocate an official descriptor name for the "advisory" attribut * e? * (PS: Have you heard any reaction about that since my writeup of it?) Sorry Dale, I just got back from Pisa from a PRIDE course and am off for the next on Sunday. But, here they are: ATTR av advisory ATTR tr as-transit * While you're at it, how about one for the experimental "as-transit", too? Cheers, -Marten -------- Logged at Wed Nov 16 15:58:42 MET 1994 --------- From Marten.Terpstra at ripe.net Wed Nov 16 15:58:40 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Wed, 16 Nov 1994 15:58:40 +0100 Subject: prdb format error Message-ID: <9411161458.AA15346@ncc.ripe.net> Folks, Some comments about the ripe-181 format of the prdb as available on fox.merit.edu: *an: AS3333 *mb: MAINT-AS3333 *sn: RIPE-ASNBLOCK4 *ch: nsfnet-admin at merit.edu 940422 *so: PRDB - has a probably typo for as-name, not *sn but should be *aa. - Better not to put in non-existing mnt-by attributes, *very* misleading. - have you renamed local-route to advisory? If so then we should all use *av - minor, masks are missing in ifaddr for inet-rtr objects for the enss's -Marten -------- Logged at Wed Nov 16 17:29:38 MET 1994 --------- From Marten.Terpstra at ripe.net Wed Nov 16 17:29:36 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Wed, 16 Nov 1994 17:29:36 +0100 Subject: cool stuff Message-ID: <9411161629.AA16551@ncc.ripe.net> Folks, Combining routing registry information can make things look very nice: [rijp-25] ./prtraceroute -lv ftp.barrnet.net traceroute with AS and policy additions [Nov 16 16:12:29 UTC] from AS3333 rijp.ripe.net (193.0.0.132) to AS200 NIC1.BARRNET.NET (131.119.245.5) 1 AS3333 Amsterdam 193.0.0.158 [I] 2 2 2 ms 2 AS1128 Amsterdam1.Dante.net 192.87.4.35 [E1] 12 4 9 ms 3 AS1804 icm-dante.icp.net 194.41.0.18 [E1] 712 608 ms 4 AS1800 icm-dc-1-E4/2.icp.net 192.157.65.73 [?] 675 644 ms 5 AS1800 icm-fix-e-H2/0-T3.icp.net 192.157.65.122 [I] 1784 467 ms 6 AS690 mf-0.enss145.t3.ans.net 192.203.229.246 [?] 354 362 347 ms 7 AS690 t3-2.cnss56.Washington-DC.t3.a 140.222.56.3 [I] 371 372 347 ms 8 AS690 t3-0.cnss32.New-York.t3.ans.ne 140.222.32.1 [I] 363 422 399 ms 9 AS690 t3-0.cnss48.Hartford.t3.ans.ne 140.222.48.1 [I] 349 352 364 ms 10 AS690 t3-2.cnss40.Cleveland.t3.ans.n 140.222.40.3 [I] 401 396 513 ms 11 AS690 t3-2.cnss25.Chicago.t3.ans.net 140.222.25.3 [I] 551 490 372 ms 12 AS690 t3-1.cnss8.San-Francisco.t3.an 140.222.8.2 [I] 473 430 427 ms 13 AS690 mf-0.cnss11.San-Francisco.t3.a 140.222.8.195 [I] 461 459 521 ms 14 AS690 t3-0.enss128.t3.ans.net 140.222.128.1 [I] 431 461 467 ms 15 AS200 SU-SP.BARRNET.NET 192.31.48.201 [?] 497 449 425 ms 16 AS200 NIC1.BARRNET.NET 131.119.245.5 [I] 510 497 425 ms AS Path followed: AS3333 AS1128 AS1804 AS1800 AS690 AS200 AS3333 = RIPE NCC AS1128 = EuropaNET (Amsterdam and Geneva PoPs) AS1804 = ICMNET-6 AS1800 = ICM-Atlantic AS690 = NSFNET Configurations AS200 = BARRNET-AS This is when I was playing with the latest version of prtraceroute that understands the new ripe-181 format for as-in/out and routes, plus also inet-rtr. It actually needs info on inet-rtr because host address 192.203.229.246 is only available in the MERIR PRDB as an interface of ENSS 145.... We'll get there ... ;-) prpath is next. Also I am doing this to test our new database machine. We have a Sparc-5 clone to replace the ELC we have been running the database on for years. Quite an improvement in indexing and lookups.... -Marten -------- Logged at Wed Nov 16 18:43:46 MET 1994 --------- From dsj at merit.edu Wed Nov 16 18:43:39 1994 From: dsj at merit.edu (Dale S. Johnson) Date: Wed, 16 Nov 1994 12:43:39 -0500 Subject: prdb format error Message-ID: <199411161743.MAA20368@merit.edu> Marten, Thanks for the pointers. And your prtraceroute is beautiful!! :-) > Folks, > > Some comments about the ripe-181 format of the prdb as available on > fox.merit.edu: > > *an: AS3333 > *mb: MAINT-AS3333 > *sn: RIPE-ASNBLOCK4 > *ch: nsfnet-admin at merit.edu 940422 > *so: PRDB > > - has a probably typo for as-name, not *sn but should be *aa. Ok; fixed. (Actually our name predates RIPE accepting this attribute, but this definitely was out of sync). > - Better not to put in non-existing mnt-by attributes, *very* > misleading. Oh yuck. Fixing this requires joining data from two different databses. I'll put this on the queue. (The data is correct fot the ASs for which we have contact information, but I need to stop producing mnt-by for ASs for which we have no contact info). > - have you renamed local-route to advisory? If so then we should > all use *av Yes, we have converted, and MCI is converting today. > - minor, masks are missing in ifaddr for inet-rtr objects for the enss's Ok; fixed. > -Marten --Dale -------- Logged at Wed Nov 16 19:33:21 MET 1994 --------- From cengiz at ISI.EDU Wed Nov 16 19:32:18 1994 From: cengiz at ISI.EDU (Cengiz Alaettinoglu) Date: Wed, 16 Nov 1994 10:32:18 -0800 Subject: cool stuff In-Reply-To: <9411161629.AA16551@ncc.ripe.net> References: <9411161629.AA16551@ncc.ripe.net> Message-ID: <199411161832.AA05648@chl.isi.edu> Marten Terpstra (Marten.Terpstra at ripe.net) on November 16: > > Folks, > > Combining routing registry information can make things look very nice: > > [rijp-25] ./prtraceroute -lv ftp.barrnet.net > traceroute with AS and policy additions [Nov 16 16:12:29 UTC] Very cool indeed. Is new prtraceroute released? May I get a copy? Cengiz -- Cengiz Alaettinoglu Information Sciences Institute cengiz at isi.edu University of Southern California -------- Logged at Wed Nov 16 20:04:15 MET 1994 --------- From Marten.Terpstra at ripe.net Wed Nov 16 20:02:57 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Wed, 16 Nov 1994 20:02:57 +0100 Subject: cool stuff In-Reply-To: Your message of Wed, 16 Nov 1994 10:32:18 PST. <199411161832.AA05648@chl.isi.edu> Message-ID: <9411161902.AA17259@ncc.ripe.net> * Very cool indeed. Is new prtraceroute released? May I get a copy? Not yet released. The version I am using is running with some library routines which have to go in to make it one script. I am at home now, so let me send you all a version tomorrow when I am in the office. -MT -------- Logged at Thu Oct 13 13:42:40 MET 1994 --------- From Marten.Terpstra at ripe.net Wed Nov 16 20:16:42 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Wed, 16 Nov 1994 20:16:42 +0100 Subject: more on prdb format Message-ID: <9411161916.AA17341@ncc.ripe.net> Some more things on the format of prdb a la ripe-181: - I thought we agreed to store the objects without syntactic sugar? The whois server automatically inserts the sugar and if it is already in the plain db file, it will show up twice in the whois output .... - there are some extra keywords for the peer definition in an inet-rtr which are not ripe-181, what are we going to do with them? Examples: *pe: 144.171.1.254 AS2649 BGP passive *pe: 192.231.238.3 AS2020 EGP def According to the spec, after the protocol indication there can be an optional AS number only .... - then the number of AS objects that have no policy information. May of them have fake maintainers, many of them are European, and I personally do not think they should be in the prdb (or rrdb for that matter). What we have done at the NCC is simply place them in their own little database (source NCC-AS-LIST) which is simply generated automatically and provides at least a descr for all unknown ASes in the RR. I think you should only register the AS that have policy info. If not, the RRs have loads of overlapping and possibly inconsistent or differently formatted information which is no good. That's it for now, -Marten -------- Logged at Wed Nov 16 22:57:51 MET 1994 --------- From dsj at merit.edu Wed Nov 16 22:57:42 1994 From: dsj at merit.edu (Dale S. Johnson) Date: Wed, 16 Nov 1994 16:57:42 -0500 Subject: more on prdb format Message-ID: <199411162157.QAA11195@merit.edu> Marten, > From marten at ripe.net Wed Nov 16 14:19:42 1994 > To: rr-impl at ripe.net > Subject: more on prdb format > From: Marten Terpstra > Date: Wed, 16 Nov 1994 20:16:42 +0100 > Sender: Marten.Terpstra at ripe.net > > > Some more things on the format of prdb a la ripe-181: > > - I thought we agreed to store the objects without syntactic sugar? > The whois server automatically inserts the sugar and if it is already > in the plain db file, it will show up twice in the whois output .... Ok; I'm changing this now. Again, this code predates the decision about syntatic sugar. > - there are some extra keywords for the peer definition in an inet-rtr > which are not ripe-181, what are we going to do with them? Examples: > *pe: 144.171.1.254 AS2649 BGP passive > *pe: 192.231.238.3 AS2020 EGP def > > According to the spec, after the protocol indication there can be an > optional AS number only .... Yes, this is problem. I doubt we can generate AS690 configs without this information, or that any else can generate their configs without it, either. Suggestions? > - then the number of AS objects that have no policy information. May > of them have fake maintainers, many of them are European, and I > personally do not think they should be in the prdb (or rrdb for that > matter). Sounds like a problem for the GRR meeting at the IETF. You don't want to throw away the AS-name information just because there isn't any policy registered for it, because then prtraceroute etc. become much less valuable tools. There should be a good way of picking the "best" (or, probably, most authorative) source for data to be used by tools. Eliminating maintainer objects for which we have no contact information has been on my queue for about three hours now; that one will get solved when I get some time. > What we have done at the NCC is simply place them in their > own little database (source NCC-AS-LIST) which is simply generated > automatically and provides at least a descr for all unknown ASes in > the RR. How is this different from having these little records in the prdb.db? > I think you should only register the AS that have policy info. > If not, the RRs have loads of overlapping and possibly inconsistent or > differently formatted information which is no good. Again, refusing to know the name of an AS because they haven't yet registered their policy strikes me as a bit self-defeating. Overlapping and therefore potentially inconsistent data is probably the central problem of the GRR; we have it in a lot more cases than just this. > That's it for now, > > -Marten --Dale -------- Logged at Thu Nov 17 00:02:41 MET 1994 --------- From Marten.Terpstra at ripe.net Thu Nov 17 00:02:25 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Thu, 17 Nov 1994 00:02:25 +0100 Subject: more on prdb format In-Reply-To: Your message of Wed, 16 Nov 1994 16:57:42 EST. <199411162157.QAA11195@merit.edu> Message-ID: <9411162302.AA18312@ncc.ripe.net> * > Some more things on the format of prdb a la ripe-181: * > * > - I thought we agreed to store the objects without syntactic sugar? * > The whois server automatically inserts the sugar and if it is already * > in the plain db file, it will show up twice in the whois output .... * * Ok; I'm changing this now. Again, this code predates the decision about * syntatic sugar. OK, excellent. * > - there are some extra keywords for the peer definition in an inet-rtr * > which are not ripe-181, what are we going to do with them? Examples: * > *pe: 144.171.1.254 AS2649 BGP passive * > *pe: 192.231.238.3 AS2020 EGP def * > * > According to the spec, after the protocol indication there can be an * > optional AS number only .... * * Yes, this is problem. I doubt we can generate AS690 configs without * this information, or that any else can generate their configs without * it, either. Suggestions? Not sure. Perhaps we need some experimental extensions to the inet-rtr object... You are probably closer to knowing what you want than us. I would like to keep the attributes as they are defined now as they are and any extra stuff needed should move to new (experimental) attributes. We can't have a stable set of attributes if we keep changing the form of them. This will confuse too many people. * > - then the number of AS objects that have no policy information. May * > of them have fake maintainers, many of them are European, and I * > personally do not think they should be in the prdb (or rrdb for that * > matter). * * Sounds like a problem for the GRR meeting at the IETF. You don't * want to throw away the AS-name information just because there isn't any * policy registered for it, because then prtraceroute etc. become much * less valuable tools. There should be a good way of picking the "best" * (or, probably, most authorative) source for data to be used by * tools. Definately yes. Let's take this up at the GRR meeting. * Eliminating maintainer objects for which we have no contact information * has been on my queue for about three hours now; that one will get solved * when I get some time. No problem, all these comments were purely things that I noticed. Now that we have a real spec in ripe-181, we should try and stick to it. We should start with a stable set and only after that move on. * > What we have done at the NCC is simply place them in their * > own little database (source NCC-AS-LIST) which is simply generated * > automatically and provides at least a descr for all unknown ASes in * > the RR. * * How is this different from having these little records in the * prdb.db? Slightly in semantics. The AS list we keep is not part of the routing registry as such. Again, we should take these issues up with the general data distribution model. * > I think you should only register the AS that have policy info. * > If not, the RRs have loads of overlapping and possibly inconsistent or * > differently formatted information which is no good. * * Again, refusing to know the name of an AS because they haven't yet * registered their policy strikes me as a bit self-defeating. Overlapping * and therefore potentially inconsistent data is probably the central * problem of the GRR; we have it in a lot more cases than just this. In my view (but I can be wrong) it is more what info is in a RR as opposed to info being used by the tools ... Not a big deal, a data distribution model should solve these things. -Marten -------- Logged at Thu Nov 17 14:43:22 MET 1994 --------- From Marten.Terpstra at ripe.net Thu Nov 17 14:43:19 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Thu, 17 Nov 1994 14:43:19 +0100 Subject: Fixes for whoisd.pl Message-ID: <9411171343.AA25480@ncc.ripe.net> Folks, whoisd.pl had some problems when interacting with the tools. Also some other little things are fixed. Also new versions for syntax.pl and cldb.pl are coming up. Please replace/intergate versions you may have. Please note these modules are for the *new* database software.... -Marten #!PERL # whoisd - whois Internet daemon # # $RCSfile: whoisd.pl,v $ # $Revision: 0.43 $ # $Author: marten $ # $Date: 1994/11/16 15:57:40 $ # @INC = ("LIBDIR", @INC); require "getopts.pl"; require "rconf.pl"; require "dbopen.pl"; require "dbclose.pl"; require "enread.pl"; require "enwrite.pl"; require "enkeys.pl"; require "enukey.pl"; require "getopt.pl"; require "misc.pl"; require "dbmatch.pl"; require "syslog.pl"; require "template.pl"; # If we get a SIGALRM, exit. Used in the read loop, to make sure people # do not keep the connection open, and open and open .... sub alarmhandler { print NS "Timeout... Closing connection\n"; close(NS); exit; } # # makekeys - converts a whitespace seperated string of keys into # an array. Trailing zeros in netnumbers are removed. # # This also does the classless indexes if a classless address is # requested. The classless index will return db keys, so they will # simply be added to the set of keys to look up. sub makekeys { local($string) = @_; local(@keys) = (); local($i); $string =~ s/^\s+//; $string =~ tr/A-Z/a-z/; @keys = split(/\s+/, $string); # remove keys shorter than 2 chars, since the indexing does not use # them either ;-) foreach $i (0..$#keys) { if (length($keys[$i]) < 2) { splice(@keys, $i, 1); } # Remember: numbers possibly followed by dots and more numbers # are ALWAYS considered IP network numbers!!!!! if ($keys[$i] =~ /^\d+[\.\d\/]*$/) { local($p, $l) = split(/\//, $keys[$i]); if (!$l) { $keys[$i] = &quad2int($p)."/32"; } else { $keys[$i] = &quad2int($p)."/$l"; } } if (length($keys[$i]) < 2) { splice(@keys, $i, 1); } } return @keys; } # # lookupandprint - will find all matches for all keys, and will output # the objects found, if they indeed match all the keys. # will also generate an array with keys that should be # looked up recursively because they are referenced in # the printed objects # # Exit codes (set in $result): # -1 - toomany hits (if result != 1 yet) # 0 - no match (if $result was not defined yet) # 1 - OK, something was output (always) sub lookupandprint { local(*db, *keys, $nonintersect) = @_; local(%en) = (); local(@playkeys) = @keys; local(@matches) = (); local($save) = ""; local($i); return if eof(db); print STDERR "($$) in lookupandprint - \$nonintersect = $nonintersect\n" if $debug; foreach $i (0..$#playkeys) { next if $playkeys[$i] !~ /^\d+\/\d+$/; if ($opt_m || $opt_M) { print NS "% This may take some time, server running at low priority\n" if !$slow_msg_print; print NS "\n" if !$slow_msg_print; $slow_msg_print = 1; system("/etc/renice 10 $$ > /dev/null 2>/dev/null"); $xsps = &findmsps($playkeys[$i], $playkeys[$i], 1, $opt_m); } else { $xsps = &findlsps($playkeys[$i], $opt_L); } local(@boe); foreach $tmp (split(/,/, $xsps)) { local($val); &getmspnxl($tmp, *val); @boe = (@boe, &cla2unikey($tmp)); } splice(@playkeys, $i, 1, @boe); } @matches = &dbmatch(*db, *playkeys, $nonintersect); if (($#matches < 0) && !defined($result)) { $result = 0; return; } for $j (0..$#matches) { if ($matches[$i] == -1) { $result = -1 if $result != 1; return; } if ($displayed{$matches[$j]}) { $result = 1; print STDERR "($$) left lookupandprint already seen\n" if $debug; next; } %en = &enread(db, $matches[$j]); local($m) = -1; if (($#playkeys > 0) && !$nonintersect) { foreach (@playkeys) { $save = $_; local(@tmp) = &enkeys(*en); @tmp = (@tmp, &enukey(*en)); foreach (@tmp) { if ($save eq $_) { $m++; } } } } else { $m = $#playkeys; } if ($m == $#playkeys) { print "\n" if &enwrite(*en, 1, 0, !$opt_S); $displayed{$matches[$j]} = 1; $result = 1; $type = &entype(*en); if ($RECUR{$type} && !$opt_r) { local(@tmp) = split(/[\s\t]+/, $RECUR{$type}); foreach (@tmp) { local(@r) = split(/\n/, $en{$_}); for ($k=0;$k<=$#r;$k++) { if (!$refd{$r[$k]}) { $refs[$recindex++] = $r[$k]; $refd{$r[$k]} = 1; } } } } } } print STDERR "($$) left lookupandprint\n" if $debug; return; } # fastlookup - small routine to do fast lookups, always non-recursive # it basically just reads from a file, and outputs as fast as it can # without interpreting the data. sub fastlookup { local(*db, *keys, $nonintersect) = @_; local($j) = ""; local($i); local(@playkeys) = @keys; return if eof(db); foreach $i (0..$#playkeys) { next if $playkeys[$i] !~ /^\d+\/\d+$/; if ($opt_m || $opt_M) { $xsps = &findmsps($playkeys[$i], $playkeys[$i], 1, $opt_m); } else { $xsps = &findlsps($playkeys[$i], $opt_L); } local(@boe); foreach $tmp (split(/,/, $xsps)) { local($val); &getmspnxl($tmp, *val); @boe = (@boe, &cla2unikey($tmp)); } splice(@playkeys, $i, 1, @boe); } local(@matches) = &dbmatch(*db, *playkeys, $nonintersect); foreach $j (@matches) { $result = 1; seek(db, $j, 0); while () { print; last if /^\s*$/; } print "\n" if eof(db); } } # # whois - main lookup loop. will output all objects found for all sources # requested. will also process the recursive lookups generated # by lookupandprint() # #sub whois { # # local(*sources, $searchstring) = @_; # # local(@keys) = &makekeys($searchstring); # # print STDERR "($$) in whois\n" if $debug; # # foreach (@sources) { # %displayed = (); # local(*i) = 'currentdb'; # &dbopen(i, $DBFILE{$_}); # if ($opt_F) { # &fastlookup(*i, *keys); # } else { # &lookupandprint(*i, *keys); # } # for ($j=0;$j<$recindex;$j++) { # local(@refkeys) = &makekeys($refs[$j]); # &lookupandprint(*i, *refkeys); # } # undef(@refs); # $recindex=0; # &dbclose(*i); # } # print STDERR "($$) left whois\n" if $debug; #} # This is already the new version of this sub for the split database sub whois { local(*sources, $searchstring) = @_; local($nonintersect) = 1; local(@keys) = &makekeys($searchstring); if ($#keys > 0) { $nonintersect = 0; } local(%nothing) = (); print STDERR "($$) in whois\n" if $debug; foreach (@sources) { %displayed = (); local(@searchdb) = (); local(*i) = 'currentdb'; local($source) = $_; if ($TYPE{$source} eq "SPLIT") { # Here is some guess work about what file to open.... # We can only do that if there is only one key. if (!$keys[1]) { if ($keys[0] =~ /^\d+\/\d+/) { @searchdb = ("in", "ir", "rt"); } elsif ($keys[0] =~ /^as\d+$/) { @searchdb = ("an"); } elsif ($keys[0] =~ /^as\-/) { @searchdb = ("am"); } } if (!$searchdb[0]) { @searchdb = keys %OBJATSQ; } if ($opt_T) { @searchdb = @onlysearch; } foreach $j (@searchdb) { $CUROBJTYPE = $j; next if !&dbopen(i, *nothing, 0, "$DBFILE{$source}.$j"); &dbclopen(*nothing, 0, "$DBFILE{$source}.$j"); if ($opt_F) { &fastlookup(*i, *keys, $nonintersect); } else { &lookupandprint(*i, *keys, $nonintersect); } &dbclose(*i); &dbclclose(); } for ($j=0;$j<$recindex;$j++) { local(@refkeys) = &makekeys($refs[$j]); @searchdb = ("pn"); foreach $j (@searchdb) { next if !&dbopen(i, *nothing, 0, "$DBFILE{$source}.$j"); &dbclopen(*nothing, 0, "$DBFILE{$source}.$j"); &lookupandprint(*i, *refkeys); &dbclose(*i); &dbclclose(); } } undef(@refs); $recindex=0; } else { &dbopen(i, *nothing, 0, $DBFILE{$source}); &dbclopen(*nothing, 0, $DBFILE{$source}); if ($opt_F) { &fastlookup(*i, *keys, $nonintersect); } else { &lookupandprint(*i, *keys, $nonintersect); } for ($j=0;$j<$recindex;$j++) { local(@refkeys) = &makekeys($refs[$j]); &lookupandprint(*i, *refkeys); } &dbclose(*i); &dbclclose(); undef(@refs); $recindex=0; } } print STDERR "($$) left whois\n" if $debug; } # # parse - parses the command line string for special options and sets # appropriate variables # sub parse { local($string) = @_; print STDERR "($$) got in parse\n" if $debug; # Reset all command line arguments, except -k @source = (); @onlysearch = (); $opt_a = 0; $opt_r = 0; $opt_F = 0; $opt_s = 0; $opt_L = 0; $opt_m = 0; $opt_M = 0; $opt_T = 0; $string =~ s/^\s+//; if ($string =~ /^help/) { open (HELP, $HELP); while () { print; } close(HELP); &syslog("QRYLOG","($$) [] 1 $name help"); exit; } while ($string =~ /^-/) { if ($string =~ s/^-([arkFLmMS]+)\s*//) { if (length($1) > 1) { foreach (split(/|/, $1)) { eval "\$opt_$_ = 1;"; } } else { eval "\$opt_$1 = 1;"; } next; } if ($string =~ s/^-(s)\s+(\S+)\s*//) { local($src) = $2; $src =~ tr/a-z/A-Z/; @source = (@source, $src); $opt_s = 1; next; } if ($string =~ s/^-V(..[0-9]+[0-9\.]*)\s*//) { $opt_V = $1; next; } if ($string =~ s/^-T\s+(\S+)\s*//) { local($type) = $1; $type = $ALIAS{$1} if $ALIAS{$1}; $type = $ATTR{$1} if $ATTR{$1}; if (!$OBJATSQ{$type}) { print "% Request for unknown object type \"$type\" ignored\n"; } else { @onlysearch = (@onlysearch, $type); $opt_T = 1; } next; } if ($string =~ s/^\-t\s+(\S+)\s*//) { local($type) = $1; $type = $ALIAS{$1} if $ALIAS{$1}; $type = $ATTR{$1} if $ATTR{$1}; if (!$OBJATSQ{$type}) { print "% No template available for object \"$type\"\n"; $result = 1; $opt_t = 1; return $type; } &Template($type); $opt_t = 1; $result = 0; return $type; } last; } if ($opt_a) { @source = split(/\s+/, $ALLLOOK); } elsif (!$source[0]) { @source = split(/\s+/, $DEFLOOK); } print STDERR "($$) left parse\n" if $debug; if ($debug) { for $fl ("d","a","s","k","r","F","t","S","T","M","m","L") { if (eval "\$opt_$fl;") { if ($flags) { $flags .= ":"; } $flags .= "$fl"; } } print STDERR "($$) called with $flags\n"; } return $string; } # # Main program # # Read config file from RIPEDBCNF, or set to default. $conffile=$ENV{"RIPEDBCNF"}; $conffile= "DEFCONFIG" unless $conffile; &rconf($conffile); # If there are command line options, other than -d (for debug) # do not run as daemon, but process the command line and exit. if (($ARGV[0] ne "-d") && ($#ARGV>=0)) { local($cmdline) = ""; for $i (0..$#ARGV) { $cmdline .= $ARGV[$i]." "; } $string = &parse($cmdline); &whois(*source, $string); exit; } else { if ($ARGV[0] eq "-d") { print STDERR "($$) running in debug mode\n"; $debug = 1; } else { # detach from tty exit 0 if (fork() > 0); if (open(FILE, "/dev/tty")) { if (!ioctl(FILE,(0x20000000|(ord('t')<<8)|113),0)) { print STDERR "ioctl: $!\n" if ($debug); } close(FILE); } close(0) if -t; } } $port = 43 unless $port; print STDERR "($$) running on port $port\n" if ($debug); $AF_INET = 2; $SOCK_STREAM = 1; $SOL_SOCKET = 0xffff; $SO_REUSEADDR = 0x0004; $sockaddr = 'S n a4 x8'; ($name, $aliases, $proto) = getprotobyname('tcp'); if ($port !~ /^\d+$/) { ($name, $aliases, $port) = getservbyport($port, 'tcp'); } $this = pack($sockaddr, $AF_INET, $port, "\0\0\0\0"); select(NS); $| = 1; select(STDOUT); socket(S, $AF_INET, $SOCK_STREAM, $proto) || die "socket: $!"; setsockopt(S, $SOL_SOCKET, $SO_REUSEADDR, 1) || die "setsockopt: $!"; while (!bind(S, $this)) { if ($bindcount >= 20) { print STDERR "whoisd: bind() failed 20 times, giving up\n"; &syslog("ERRLOG", "whoisd cannot bind() for 20 times, giving up"); exit 1; } else { print STDERR "-- bind: $!, trying again\n" if ($debug); $bindcount++; sleep 5; } } if ($bindcount) { &syslog("ERRLOG", "whoisd needed $bindcount binds before succeeding"); } listen(S,5) || die "listen: $!"; select(S); $| = 1; select(STDOUT); # Set up the alarm handler $SIG{'ALRM'} = 'alarmhandler'; # We have come this far, let's write the PID to $PIDFILE, useful for # killing and stuff. if (open(PID, ">$PIDFILE")) { print PID "$$\n"; close(PID); } else { &syslog("ERRLOG", "cannot write to $PIDFILE: $!"); } # Main waiting loop, wait for connection, and fork of child to process # the incoming request for (;;) { ($addr = accept(NS,S)) || die $!; if (($child = fork()) == 0) { ($af,$port,$inetaddr) = unpack($sockaddr,$addr); @inetaddr = unpack('C4', $inetaddr); $rhost = "$inetaddr[0].$inetaddr[1].$inetaddr[2].$inetaddr[3]"; print STDERR "($$) fork connection [$rhost]\n" if $debug; local($name,$alias,$at,$len, at addr)=gethostbyaddr($inetaddr,$af); if ($name eq "") { $name = $rhost; } # Set alarm to timeout after people did not send anything # in 60 seconds alarm 60; while() { $result = 0; # Got something, reset alarm; alarm 0; chop; # we want at least some alphanumeric stuff ... if (/\w+/) { select(NS); $string = &parse($_); print STDERR "($$) lookup $string\n" if $debug; if (!$opt_t) { &whois(*source, $string); select(NS); print $NOMATCH,"\n" if $result == 0; print $TOOMANY,"\n" if $result == -1; select(STDOUT); if ($opt_k) { print NS "\n"; alarm 60; } else { close(NS); } } else { close(NS); } } # got something completely non-alphanumeric else { select(NS); $string = $_; print STDERR "($$) lookup $string\n" if $debug; print "Cannot lookup non-alphanumeric keys\n"; print "Connection closed\n"; $result = 0; select(STDOUT); close(NS); } # Log this query $flags = ""; for $fl ("d","a","s","k","r","F","t","S","T","M","m","L") { if (eval "\$opt_$fl;") { if ($flags) { $flags .= ":"; } $flags .= "$fl"; } } if ($opt_V) { if ($flags) { $flags .= ":"; } $flags .= "V$opt_V"; } &syslog("QRYLOG","($$) [$flags] $result $name $string"); } close(NS); print STDERR "($$) exit connection [$rhost]\n" if $debug; exit; } while (waitpid(-1, 1) > 0) {} } -------- Logged at Thu Nov 17 14:44:37 MET 1994 --------- From Marten.Terpstra at ripe.net Thu Nov 17 14:44:35 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Thu, 17 Nov 1994 14:44:35 +0100 Subject: cldb.pl fixes Message-ID: <9411171344.AA25499@ncc.ripe.net> # $RCSfile: cldb.pl,v $ # $Revision: 1.6 $ # $Author: marten $ # $Date: 1994/11/17 13:43:57 $ # This module contains all routines for classless indexing and lookups # and some routines to do conversions here and there require "misc.pl"; require "defines.pl"; require "time.pl"; # This is triple booo!!!! Change this !!!! # $OVERFLOWDIR = "/ncc/nccfs3/cldb/data"; # # convertonormal($cla) # # converts a integer prefix/length internal structure to a readable # quad prefix/len string sub converttonormal { local($cla) = @_; local($int, $len) = split(/\//, $cla); return &int2quad($int)."/$len"; } # # cla2unikey($cla) # # gives back an array of unique keys into the database that match this # cla. Basically it will extract all the "O" values for $mspnxl{$cla} and # put them into an array. sub cla2unikey { local($cla) = @_; local(@result) = (); local($cla2tmp); &getmspnxl($cla, *cla2tmp); while ($cla2tmp =~ s/^O([^,]+)//) { next if $1 =~ /DUMMY/; @result = (@result, $1); } return @result; } # # getmspnxl($index) # # gets the value (a string) for a certain index in the assoc array %mspnxl # because of the overflow mechanism, this could be retrieved from a file # or straight from the DBM file sub getmspnxl { local($index, *value) = @_; if ($previous eq $index) { } else { $previous = $index; } &timer("getmspnxl", 1); $value = $mspnxl{$index}; if ($value eq "ETOOBIG") { $value = ""; local($filename) = &converttonormal($index); $filename =~ s/\//\./g; local($counter) = 0; while (!open(FILE, "$OVERFLOWPREFIX.$filename")) { select(undef, undef, undef, 0.05); $counter++; if ($counter > 10) { die "major failure! cannot open $OVERFLOWPREFIX.$filename: $!"; } } sysread(FILE, $value, 1000000, 0); close(FILE); } &timer("getmspnxl", 0); return *value; } # # setmspnxl($index, $value) # # sets the value for a certain index in assoc array %mspnxl. Because of # the 1K max in DBM, the overflow mechanism must be used for large values # In the overflow mechanism, whenever a file needs to be updated, a new # file will be created, and renamed after. This is make the time the file # is not available (for servers) as short as possible. sub setmspnxl { local($index, *value, *addvalue) = @_; &timer("setmspnxl", 1); if (length($value) + length($addvalue) > 950) { if ($addvalue) { $value .= ",$addvalue"; } local($filename) = &converttonormal($index); $filename =~ s/\//\./g; # unlink("$OVERFLOWDIR/$filename.$CUROBJTYPE"); # Create a new file with new values open(FILE, "+>$OVERFLOWPREFIX.$filename,") || die "cannot open $filename: $!"; syswrite(FILE, $value, length($value), 0); close(FILE); # Move the new file to the original. rename("$OVERFLOWPREFIX.$filename,", "$OVERFLOWPREFIX.$filename"); $mspnxl{$index} = "ETOOBIG"; } else { if ($mspnxl{$index} eq "ETOOBIG") { local($filename) = &converttonormal($index); $filename =~ s/\//\./g; unlink("$OVERFLOWPREFIX.$filename"); } if ($addvalue || $value) { if ($addvalue) { $mspnxl{$index} .= ",$addvalue"; } else { $mspnxl{$index} = $value; } } else { delete $mspnxl{$index}; } } &timer("setmspnxl"); } # # old_to_new($oldnet) # # converts old style RIPE database network numbers (single classful net # and classful ranges) to prefix/length format. Prefix/length is the # internal representation used. Routine to convert a range into # prefix/length is happily stolen from "aggis" by Dale Johnson, MERIT # Thanks Dale ;-) sub old_to_new { local($oldnet) = @_; local($len); local(@returnstring) = (); local($one_net); &timer("old_to_new", 1); # Conventional classful nets if ($oldnet =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/) { if ($1 >= 192) { $len = 24; $len = 32 if $4; $one_net = 0x00000100; } elsif ($1 >= 128) { $len = 16; $one_net = 0x00010000; } else { $len = 8; $one_net = 0x01000000; } } # Special case, it can happen that we got a hostaddress and mask # let's make sure we remove the mask when we return this. # this is for ifaddr in inet-rtr if ($oldnet =~ /(\d+\.\d+\.\d+\.\d+)\s+\d+\.\d+\.\d+\.\d+/) { return "$1/$len"; } if ($oldnet !~ /\-/) { &timer("old_to_new"); return "$oldnet/$len"; } # Now, we have a classful range, let's convert this into pref/len if ($oldnet =~ /^(\d+\.\d+\.\d+\.\d+)\s+\-\s+(\d+\.\d+\.\d+\.\d+)/) { local($begin) = &quad2int($1); local($end) = &quad2int($2); local($newbegin) = $begin; while ($newbegin <= $end) { for ($pwr=1; $pwr<24; $pwr++) { $pwr2 = 2 ** $pwr; $thisend = $newbegin + ($pwr2-1)*$one_net; return @returnstring if !$newbegin; if (($thisend > $end) || $newbegin != ($newbegin & $masks[$len-$pwr])) { $pwr--; $giveback = sprintf("%s/%d", &int2quad($newbegin), $len-$pwr); @returnstring = (@returnstring, $giveback); $newbegin = $newbegin + $one_net * 2**$pwr; last; } } } } &timer("old_to_new"); return @returnstring; } # # findlsps($cla, $recursive) # # Find the list of less specifics for prefix $cla. If the recursion # flag is set, all less specifics (lsps) are returned, otherwise only # the first less specific. It is not a recursive routine, but oh well. sub findlsps { local($cla, $recurse) = @_; local($prefix, $len) = split(/\//, $cla); local($returnlist) = ""; local($ii); for ($ii=$len;$ii>=0;$ii--) { local($newcla) = ($prefix & $masks[$ii]); local($tmp); &getmspnxl("$newcla/$ii", *tmp); if ($tmp) { if ($recurse) { if ($returnlist) { $returnlist .= ",$newcla/$ii"; } else { $returnlist = "$newcla/$ii"; } } else { return "$newcla/$ii"; } } } return $returnlist; } # # findmsps($cla, $orig, $first, $nonrecurse) # # routine to find all more specifics of a certain classless address cla. # Because of recursion, it needs to remember the very first $cla it # is called with, which stays in $orig. This is needed to check whether # all found more specifics really are more specific. By default recursion # is on, it will try and find all more specifics. sub findmsps { local($cla, $orig, $first, $nonrecurse) = @_; local($j); local($msps) = ""; # Look up first less specific when the requested $cla does not # exist itself, and use that to find all more specifics. local($tmp); &getmspnxl($orig, *tmp); # Now, if this $cla does not exist itself, we can do two things, # - we can step one level back, and check all them (painful if # you have to step back to 0/0) # - allow only more specifics of prefixes that are actually # in the database, return nothing if the prefix in the DB # does not exist. # If you have indexed with priming on, the first is no problem. # If you have indexed with priming off, the first may take CPU.... # This implements the first solution if (!$tmp && $first) { $cla = (split(/\,/, &findlsps($orig)))[0]; } # And this the second solution # if (!$tmp && $first) { # return $msps; # } $tmp=""; &getmspnxl($cla, *tmp); foreach (split(/,/, $tmp)) { local($tmp); &getmspnxl($_, *tmp); if ($tmp) { local($p1, $l1) = split(/\//, $_); local($p2, $l2) = split(/\//, $orig); if (($p1 & $masks[$l2]) == ($p2 & $masks[$l2])) { if ($nonrecurse) { $msps .= "$_,"; } else { $msps .= $_ . "," . &findmsps($_, $orig,0,0); } } } } $msps; } # # givemsps($string, $cla) # # Give all more specifics of $cla that can be found in $string. I think this # can also be done by findmsps, but I'll keep it in here for now. Only # needed for insertations right now. Returns a sub-string will all more # specifics of $cla. This is a costly operations, and should only be done # for one-off insertations (like normal updates). Indexing a whole (locked) # file should not use this, the "to be inserted" cla's should be presorted. sub givemsps { local(*string, $cla) = @_; local($returnstring) = ""; # return $returnstring; &timer("givemsps", 1); local($pref, $len) = split(/\//, $cla); foreach (split(/,/, $string)) { next if $_ =~ /^O|^start$/; local($tmppref, $tmplen) = split(/\//, $_); next if $tmplen <= $len; if (($tmppref & $masks[$len]) == $pref) { if ($returnstring) { $returnstring .= ",".$_; } else { $returnstring = $_; } } } &timer("givemsps"); return $returnstring; } # # addtomspnxl($index, $value) # # Adds $value to the current value of $mspnxl{$index}. It is a wrapper # for setmspnxl sub addtomspnxl { local($index, *value) = @_; &timer("addtomspnxl", 1); local($addtotmp); &getmspnxl($index, *addtotmp); if ($addtotmp) { &setmspnxl($index, *addtotmp, *value); } else { &setmspnxl($index, *value); } &timer("addtomspnxl"); } # # deletefrommspnxl($index,$value) # # Deletes $value from the current value of $mspnxl{$index}. Basically # another wrapper for setmspnxl sub deletefrommspnxl { local($index, *value) = @_; local($j); local($deletetmp); &getmspnxl($index, *deletetmp); foreach $j (split(/,/, $value)) { if ($deletetmp =~ s/^$j$//g) {} elsif ($deletetmp =~ s/^$j,//g) {} elsif ($deletetmp =~ s/,$j,/,/g) {} elsif ($deletetmp =~ s/,$j$//g) {} } &setmspnxl($index, *deletetmp); } # # inscla($cla, $offset) # # Insert classless address $cla, which has an offset in the database # of $offset, into the tree structure # ! New version that does not store offsets but references to unique # ! keys, which makes the lookup indirect, but makes the classless # ! index independent of the offsets and thus the clean # # Extra flag mspscheck says whether or not a check should be made # for existing more specifics. When using netdbm, they are presorted # and do not have to be msp-checked. For normal insertions, they # should be checked. The reason this is optional is because givemsps # can be quite costly in time.... sub inscla { # local($cla, $offset, $mspscheck) = @_; local($cla, $uniquekey, $mspscheck) = @_; local($j); local($p); if (!$mspnxl{"0/0"}) { $mspnxl{"0/0"} = "start"; } print STDERR "inscla($cla) called\n" if $debug; local($prefix, $len) = split(/\//, $cla); for ($p=$len;$p>=0;$p--) { local($newcla) = ($prefix & $masks[$p]); local($tmp2); &getmspnxl("$newcla/$p", *tmp2); if ($tmp2) { local($tmp); &getmspnxl($cla, *tmp); if (!$tmp) { local($tmp4) = "O$uniquekey"; &setmspnxl($cla, *tmp4); &addtomspnxl("$newcla/$p", *cla); } else { local($tmp) = "O$uniquekey,$tmp"; &setmspnxl($cla, *tmp); } if ($mspscheck) { local($msps) = &givemsps(*tmp2, $cla); &addtomspnxl($cla, *msps); &deletefrommspnxl("$newcla/$p", *msps); } $p=0; } } } # # delcla($cla) # # Delete a classless address from the internal tree structure sub delcla { local($cla) = @_; &timer("delcla",1); local($q); local($prefix, $len) = split(/\//, $cla); for ($q=$len-1;$q>=0;$q--) { local($newcla) = ($prefix & $masks[$q]); local($tmp2); &getmspnxl("$newcla/$q", *tmp2); if ($tmp2) { &deletefrommspnxl("$newcla/$q", *cla); local($tmp); &getmspnxl($cla, *tmp); if ($tmp) { local($nothing); $tmp =~ s/^[^,]+[,]*//; &addtomspnxl("$newcla/$q", *tmp) if ($tmp ne ""); &setmspnxl($cla, *nothing, *nothing); } $q = 0; } } &timer("delcla"); } -------- Logged at Thu Nov 17 14:45:08 MET 1994 --------- From Marten.Terpstra at ripe.net Thu Nov 17 14:45:04 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Thu, 17 Nov 1994 14:45:04 +0100 Subject: syntax.pl fixes Message-ID: <9411171345.AA25518@ncc.ripe.net> # # $RCSfile: syntax.pl,v $ # $Revision: 0.46 $ # $Author: marten $ # $Date: 1994/11/17 13:38:27 $ # # ARGUMENTS: *ASSOC object # RETURNS: INTEGER object_status # # Object status = $O_OK, $O_WARNING, $O_ERROR # Object will be changed to have warnings and errors # # This is the really ugly bit, where the syntax of all the fields is checked # This is completely independent of the config file and needs additions if # you add your own fields. It does not check whether fields are allowed in # this object, whether they are supposed to be multiple or any of that # That part is basic configuration driven and can be found in enparse.pl # # The syntax stuff needs to be re-written at a later date to allow for # configurable syntax. This is in the dreams of someones mind..... # require "adderror.pl"; require "net2net.pl"; # various routines to make classless life easier require "misc.pl"; # this one has quite a few used sub routines require "maintainer.pl"; # For mnt-by verification sub checksyntax { local(*object) = @_; local($rtcode) =$O_OK; local($itmp, $val, $msg); print STDERR "checksyntax - called\n" if $opt_V; foreach $itmp (keys %object) { if ($object{$itmp} eq "") { ($val, $msg) = &dosyntax($itmp, "", *object); if ($val == $O_WARNING) { &addwarning(*object, $msg); $rtcode = $O_WARNING if $rtcode == $O_OK; } elsif ($val == $O_ERROR) { &adderror(*object, $msg); $rtcode = $O_ERROR; } } else { # # Got to preprocess the multi-line semantic attributes. sigh.. Did I really # think this was a good idea ?? # The way this works is $peer and $wt (this is a combination depending on the # attribute) are used as a key to check wrapped lines. # This is probably not the best way of doing this as you to do a lot of # splitting to get the correct unique keys. # You also have to split differently depending on whether syntax sugar exists. # if($itmp eq "ai" || $itmp eq "ao" || $itmp eq "it" || $itmp eq "io") { local($FLAG) = $itmp; local(@array) = split(/\n/, $object{$itmp}); local($j,$k) = 0; local(%linewrap) = (); local(%newval) = (); foreach $j (0..$#array) { # # as-in lines # if($FLAG eq "ai") { if($array[$j] =~ /^from/) { ($sugar1, $peer, $wt, $sugar2, $pol) = split(/\s+/, $array[$j], 5); if($sugar2 ne "accept") { &adderror(*object, "keyword problem in as-in line for peer $peer cost $wt"); $rtcode = $O_ERROR; next; } } else { ($peer, $wt, $pol) = split(/\s+/, $array[$j], 3); } $object{$itmp} =~ s/from\s+|accept\s+//g; # # as-out lines # } elsif ($FLAG eq "ao") { if($array[$j] =~ /^to/) { ($sugar1, $peer, $sugar2, $pol) = split(/\s+/, $array[$j], 4); $wt = 1; if($sugar2 ne "announce") { &adderror(*object, "keyword problem in as-out line for peer $peer"); $rtcode = $O_ERROR; next; } } else { ($peer, $pol) = split(/\s+/, $array[$j], 2); $wt = 1; } $object{$itmp} =~ s/to\s+|announce\s+//g; # # interas-in lines # } elsif ($FLAG eq "it") { # # Get rid of spaces in (=) # $array[$j] =~ s/\(\s*pref\s*\=\s*(\S+)\s*\)/\(pref=\1\)/; if($array[$j] =~ /^from/) { ($sugar1, $peer, $lid, $rid, $cost, $sugar2, $pol) = split(/\s+/, $array[$j], 7); if($sugar2 ne "accept") { &adderror(*object, "keyword problem in interas-in line for peer $peer cost $cost"); $rtcode = $O_ERROR; next; } $wt = "$lid-$rid-$cost"; } else { ($peer, $lid, $rid, $cost, $pol) = split(/\s+/, $array[$j], 5); $wt = "$lid-$rid-$cost"; } $object{$itmp} =~ s/from\s+|accept\s+//g; # # interas-out lines # } elsif ($FLAG eq "io") { local($gotmet) = 0; # # This is where you have insert new ``mertic-type'' values and get rid of # spaces # if ($array[$j] =~ /metric-out/) { $array[$j] =~ s/\(\s*metric\-out\s*\=\s*(\S+)\s*\)/\(metric-out=\1\)/; $gotmet = 1; } if($array[$j] =~ /^to/) { if($gotmet) { ($sugar1, $peer, $lid, $rid, $metric, $sugar2, $pol) = split(/\s+/, $array[$j], 7); $wt = "$lid-$rid-$metric"; } else { ($sugar1, $peer, $lid, $rid, $sugar2, $pol) = split(/\s+/, $array[$j], 6); $wt = "$lid-$rid"; } if($sugar2 ne "announce") { &adderror(*object, "keyword problem in interas-out line for peer $peer"); $rtcode = $O_ERROR; next; } } else { if($gotmet) { ($peer, $lid, $rid, $metric, $pol) = split(/\s+/, $array[$j], 5); $wt = "$lid-$rid-$metric"; } else { ($peer, $lid, $rid, $pol) = split(/\s+/, $array[$j], 4); $wt = "$lid-$rid"; } } $object{$itmp} =~ s/to\s+|announce\s+//g; } # # Now finally check if the lines are the same. # if($newval{"$peer:$wt"}) { if($linewrap{"$peer:$wt"}) { $newval{"$peer:$wt"} = $newval{"$peer:$wt"}." ".$pol; } else { $newval{"$peer:$wt"} = $newval{"$peer:$wt"}."\n".$array[$j]; } } else { $newval{"$peer:$wt"} = $array[$j]; } $linewrap{"$peer:$wt"} = 1; } # # Now loop through the value and syntax check the re-built line # foreach $k (keys %newval) { foreach $l (split(/\n/, $newval{$k})) { local($val, $msg) = &dosyntax("$FLAG", $l, *object); if ($val == $O_WARNING) { &addwarning(*object, $msg); $rtcode = $O_WARNING if $rtcode == $O_OK; } elsif ($val == $O_ERROR) { &adderror(*object, $msg); $rtcode = $O_ERROR; } } } # # Otherwise just split on newlines and pass line by line to syntax checker # } else { foreach $j (split(/\n/, $object{$itmp})) { local($val, $msg) = &dosyntax($itmp, $j, *object); if ($val == $O_WARNING) { &addwarning(*object, $msg); $rtcode = $O_WARNING if $rtcode == $O_OK; } elsif ($val == $O_ERROR) { &adderror(*object, $msg); $rtcode = $O_ERROR; } } } } } print STDERR "checksyntax - returned\n" if $opt_V; return $rtcode; } sub dosyntax { local($key, $value, *object) = @_; # # THE FIRST SET OF ATTRIBUTES MAY NOT HAVE AN EMPTY VALUE IF THEY EXIST # # # ua - authorise # if ($key eq "ua") { if ($value !~ /\S/) { return $O_ERROR, "illegal authorisation value"; } return; } # # uo - override # if ($key eq "uo") { if ($value !~ /\S/) { return $O_ERROR, "illegal override value"; } } # # ud - delete # # The delete is a bit of a pain. Since we want to be able to delete # objects that actually contain syntax errors, they are NOT syntax # checked. Therefore, all the syntax checking for deletes is actually # done in misc.pl sub &hasdelete. This is not very nice, but the only # thing that actually works. Below is commented out. # if ($key eq "ud") { # if ($value !~ /\S/) { # return $O_ERROR, "delete attribute must contact email address and reason for delete"; # } # return; # } # # # AFTER THIS, ATTRIBUTES THAT ARE DEFINES BUT EMPTY ARE OK # return if $value eq ""; # # aa - see na # # # ac - admin-c # if ($key eq "ac") { if (!&isname($value)) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # ad - address # if ($key eq "ad") { if ($value !~ /^.*$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # ae - as-exclude # if ($key eq "ae") { local($sugar1, $as, $sugar2, $rest) = ""; if($value =~ /^exclude/) { ($sugar1, $as, $sugar2, $rest) = split(/\s+/, $value, 4); if($sugar2 ne "to") { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } } else { ($as, $rest) = split(/\s+/, $value,2); } if(!&isasnum($as)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\" - neigbor peer". " $as doesn't look like an AS"; } if(&isasnum($rest) || &iscommunity($rest) || &isasmacro($rest) || ($rest eq "ANY")) { $object{$key} =~ s/exclude\s+|to\s+//g; } else { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\" - exclude-route-keyword". " $rest unknown"; } return; } # # ai - as-in # if ($key eq "ai") { # # This line has been pre-processed above. # remove syntax fluff, flip to unpper case for ases and remove leading WS # $value =~ s/from\s*//; $value =~ s/accept\s*//; $value =~ s/[aA][sS]/AS/g; $value =~ s/^\s+//; # # split the line up into AS, cost and the policy # local($as,$pref,$pol) = split(/\s+/,$value,3); if (!&isasnum($as)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\"\nneigbour peer". " $as doesn't look like an AS"; } if (!$pref) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\"\nyou must give a cost"; } if (!&isaspref($pref)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\"\ncost $pref ". "must be a positive integer"; } if (!$pol) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\"\n\tno ". "routing policy expression given"; } # # now check equal brackets and braces # if(!&isbracket($pol)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: peer $as cost $pref\"" . "\n\tunequal brackets \"\(\)\"\n"; } if(!&isbrace($pol)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: peer $as cost $pref\"" . "\n\tunequal braces \"\{\}\"\n"; } # # Now grab the netlist entries and check they are ok # local($tmppol) = $pol; while($tmppol =~ s/(\{[^\}]*\})// ) { if(!&isnetlist($1)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: peer $as cost $pref\"". "\n\tnetlist error $1"; } } # # Now check the actual keywords # while($tmppol =~ s/(\S+)//) { if (!&isaskeyword($1)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: peer $as cost $pref\"\n\t$1 ". "is not a routing policy KEYWORD"; } } return; } # # al - as-list # if ($key eq "al") { $value =~ tr/a-z/A-Z/; local(@aslist) = split(/\s+/, $value); local($i); foreach $i (@aslist) { if(!&isasnum($i) && !&isasmacro($i)) { return $O_ERROR, "illegal value \"$i\" in \"$ATTL{$key}\""; } } return; } # # an - aut-num # if ($key eq "an") { $value =~ tr/a-z/A-Z/; if (!&isasnum($value)) { return $O_ERROR, "syntax error in \"$ATTL{$key}\" - $value is not a valid AS"; } if (($object{$key} =~ tr/a-z/A-Z/)) { return $O_WARNING, "\"$ATTL{$key}\" value uppercased"; } return; } # # am - as-macro # if ($key eq "am") { if(!&isasmacro($value)) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # ao - as-out # if ($key eq "ao") { $value =~ s/to//; $value =~ s/announce//; $value =~ s/[aA][sS]/AS/g; $value =~ s/^\s+//; # # split up into AS and policy # local($as,$pol) = split(/\s+/,$value,2); if (!&isasnum($as)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\" - ". "neigbour peer $as doesn't look like an AS"; } if (!$pol) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\" - ". "no routing policy expression given"; } # # now check equal brackets and braces. # if(!&isbracket($pol)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: peer $as \"" . "\n\tunequal brackets \"\(\)\"\n"; } if(!&isbrace($pol)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: peer $as \"" . "\n\tunequal brackets \"\(\)\"\n"; } # # Now grab loop through netlist entries and check they are ok # Here a netlist entry is anything between braces. # local($tmppol) = $pol; while($tmppol =~ s/(\{[^\}]*\})// ) { if(!&isnetlist($1)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: peer $as \"". "\n\tnetlist error $1"; } } while($tmppol =~ s/(\S+)//) { if (!&isaskeyword($1)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: peer $as \"". "\n\t$1 is not a routing policy KEYWORD"; } } } # # as - aut-sys # if ($key eq "as") { if ($value !~ /^\d+$/) { if (!&isasnum($value)) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } } return; } # # at - auth # if ($key eq "at") { local(@authstr) = split(/\s+/, $value, 2); if ($authstr[0] eq "NONE") { if ($authstr[1] !~ /^$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}\"". "- $authstr[1] is extraneous for $authstr[0]"; } else { return; } } if ($authstr[0] eq "CRYPT-PW") { if(length($authstr[1]) != 13) { return $O_ERROR, "syntax error in \"$ATTL{$key}\"" . " - password \"$authstr[1]\" is incorrect length"; } else { return; } } elsif ($authstr[0] ne "MAIL-FROM") { return $O_ERROR, "syntax error in \"$ATTL{$key}\" $value"; } return; } # # au - authority # if ($key eq "au") { if ($value !~ /^[a-zA-Z0-9\-\.\ \,\(\)\/]+$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # av - advisory # if ($key eq "av") { local(@list) = split(/\s+/, $value); if (!&isasnum($list[0])) { return $O_ERROR, "syntax error in \"$ATTL{$key}\" - $list[0] is no a valid peer"; } return; } # # the RIPE-60 tags are just given a simple parse - not really needed # as they are basically guarded. # # bg - bdry-gw # if ($key eq "bg") { if ($value !~ /^[A-Z0-9\-]+$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # bi - bis # bis - Boundary intermediate system i.e. CLNS nonsense # if ($key eq "bi") { local(@prefixes) = split(/\s+/, $value); local($i); if ($#prefixes > 1) { return $O_ERROR, "too many prefixes in \"$ATTL{$key}\""; } foreach $i (@prefixes) { if (!&isclnsprefix($i)) { return $O_ERROR, "illegal NSAP prefix syntax in \"$ATTL{$key}\""; } } return; } # # bl - bdrygw-l # if ($key eq "bl") { if ($value !~ /^[A-Z0-9\-\ ]+$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # Try to do something clever with the changed field # # ch - changed # if ($key eq "ch") { local($i); (@tmp) = split(/\s+/, $value); $email = "$tmp[0]"; foreach $i (1..$#tmp-1) { # This is for emails with spaces ;-( $email .= " $tmp[$i]"; } $date = "$tmp[$#tmp]" if ($tmp[$#tmp] =~ /^\d+$/); if (!(&isemail($email))) { return $O_ERROR, "syntax error in e-mail part of \"$ATTL{$key}\""; } local($s, $m, $h, $md, $mo, $y) = localtime(time); $mo += 1; $md = "0".$md unless $md > 9; $mo = "0".$mo unless $mo > 9; $y = "0".$y unless $y > 9; local($curdate) = "$y$mo$md"; if ($date eq "") { $object{$key} .= " $curdate"; return $O_WARNING, "todays date ($curdate) added to \"$ATTL{$key}\" attribute"; } if ($date !~ /^(\d\d)(\d\d)(\d\d)$/) { return $O_ERROR, "date part of \"$ATTL{$key}\"". "not in YYMMDD format"; } # 1988 is the start of the world. This is where we test for proper # date values of YYMMDD if (($1 < 88) || ($2 > 12) || ($3 > 31)) { return $O_ERROR, "date part of \"$ATTL{$key}\" is not a valid YYMMDD value"; } if ($date gt $curdate) { $object{$key} =~ s/$date/$curdate/; return $O_WARNING, "date in \"$ATTL{$key}\" ($date) is in the ". "future - changed to $curdate"; } return; } # # This is the "community" stuff. # It needs to make sure RIPE-81 keywords aren't there. # # cl - comm-list # if ($key eq "cl") { local(@crap) = split(/\s+/,$value); foreach $j (@crap) { if (!&iscommunity($j)) { return $O_ERROR, "syntax error in \"$ATTL{$key}\" - ". "appears to contain a routing policy KEYWORD \"$j\""; } } return; } # # cm - community # if ($key eq "cm") { if (!&iscommunity($value)) { return $O_ERROR, "syntax error in \"$ATTL{$key}\" - appears to ". "contain a routing policy KEYWORD \"$j\""; } return; } # # co - connect # # check the list of connect values from the config. # if ($key eq "co") { foreach $j (split(/\s+/, $value)) { if (!$CONNECT{$j}) { return $O_ERROR, "unknown connect value \"$j\""; } } return; } # # cy - country # if ($key eq "cy") { if (!$COUNTRY{$value}) { return $O_ERROR, "unknown country \"$value\""; } else { if ($COUNTRY{$value} ne $value) { $object{$key} = $COUNTRY{$value}; return $O_WARNING, "country \"$value\" changed to \"$COUNTRY{$value}\""; } } return; } # # de - descr # if ($key eq "de") { if ($value !~ /^.*$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # df - default # if ($key eq "df") { local($rest) = ""; if ($object{"dp"}) { $value =~ tr/A-Z/a-z/; ($prefix, $pref,$rest) = split(/\s+/, $value, 3); if (!&isclnsprefix($prefix)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\" - incorrect ". "NSAP prefix"; } } else { $value =~ tr/a-z/A-Z/; ($as,$pref,$rest) = split(/\s+/,$value, 3); if (!&isasnum($as)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\" ". "- default peer $as doesn't look like an AS"; } } if (!$pref) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\" - you must give a cost"; } if (!&isaspref($pref)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\" - ". "cost $pref must be a positive integer"; } if($rest && !$object{"dp"}) { $rest =~ s/STATIC/static/; $rest =~ s/DEFAULT/default/; if (&isnetlist($rest) || ($rest eq "static") || ($rest eq "default")) {} else { return $O_ERROR, "syntax error in \"$ATTL{$key}\" - ". "\"$rest\" is invalid"; } $object{$key} =~ s/STATIC/static/; $object{$key} =~ s/DEFAULT/default/; $object{$key} =~ s/[aA][sS]/AS/g; } return; } # # Check to make sure the network list looks reasonable # # # di - dom-net # if ($key eq "di") { local(@list) = split(/\s+/,$value); local($j) = 0; foreach $j (0..$#list) { if (!&isnetnum($list[$j])) { return $O_ERROR, "syntax error in \"$ATTL{$key}\" - ". "illegal IP network number $list[$j]"; } } return; } # # dm - dom-in # if($key eq "dm") { local($bis,$pref, at crap) = split(/\s+/,$value); if (!&isclnsprefix($bis)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\" - dom-prefix". " $bis doesn't look like an NSAP"; } if (!$pref) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\" - you must give a cost"; } if (!&isaspref($pref)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\" - cost $pref ". "must be a positive integer"; } if ($#crap < 0 ) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\" - no ". "routing policy expression given"; } foreach $k (@crap) { if (!&isclnskeyword($k)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\" - $k ". "is not a routing policy KEYWORD"; } } return; } # # dn - domain # if ($key eq "dn") { if (!&isdomname($value)) { return $O_ERROR, "illegal domain name in $value"; } return; } # # do - dom-out # if ($key eq "do") { local($bis, at crap) = split(/\s+/,$value); if (!&isclnsprefix($bis)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\" - ". "dom-prefix \"$bis\" doesn't look like an NSAP prefix"; } if ($#crap < 0 ) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\" - ". "no routing policy expression given"; } foreach $k (@crap) { if (!&isclnskeyword($k)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\" - ". "$k is not a routing policy KEYWORD"; } } return; } # # dp - dom-prefix # if ($key eq "dp") { if (!&isclnsprefix($value)) { return $O_ERROR, "illegal NSAP prefix format in \"$ATTL{$key}\""; } return; } # # da - dom-name # if ($key eq "da") { if ($value !~ /^[a-zA-Z\-0-9\.]+$/) { return $O_ERROR, "illegal $ATTL{$key} name"; } return; } # # dt - upd-to # if ($key eq "dt") { if (!&isemail($value)) { return $O_ERROR, "syntax error in \"$ATTL{$key}\" ". "- \"$value\" is not in \(RFC822\) format"; } return; } # # em - e-mail # if ($key eq "em") { if (!&isemail($value)) { return $O_ERROR, "syntax error in \"$ATTL{$key}\" ". "- \"$value\" is not in \(RFC822\) format"; } return; } # # gd - guardian # if ($key eq "gd") { if (!(&isemail($value))) { return $O_ERROR, "syntax error in \"$ATTL{$key}\" - ". "guardian must be a mailbox entry"; } return; } # # gw - gateway # if ($key eq "gw") { if ($value !~ /^[a-zA-Z0-9\-\.\ ]+$/) { return $O_WARNING, "syntax error in \"$ATTL{$key}\""; } return; } # # ho - hole # # still need to check against route entry # if ($key eq "ho") { local($stat, $msg, @str) = &netpre_verify($value); if($stat == $NOK) { return $O_ERROR, "syntax error in \"$ATTL{$key}\"\n$msg\n"; } return; } # # if - ifaddr # if ($key eq "if") { local($if, $mask) = split(/\s+/, $value, 2); if(!&isipaddr($if)) { return $O_ERROR, "syntax error in \"$ATTL{$key}\"" . " $if is incorrect"; } if(!&ismask($mask)) { return $O_ERROR, "syntax error in \"$ATTL{$key}\"" . " $mask is incorrect"; } return; } # # ii - ias-int # if ($key eq "ii") { local(@iistr) = split(/\s+/,$value); if ($#iistr != 1 ) { return $O_ERROR, "syntax error in \"$ATTL{$key}\" - wrong number of components"; } if (!&isipaddr($iistr[0])) { return $O_ERROR, "syntax error in \"$ATTL{$key}\" - \"$iistr[0]\" ". "is not a valid IP address"; } if (!&isasnum($iistr[1])) { return $O_ERROR, "syntax error in \"$ATTL{$key}\" - ". "\"$iistr[1]\" is not a valid AS"; } return; } # # it - interas-in # if ($key eq "it") { # # This line has been pre-processed above. # remove syntax fluff, flip to unpper case for ases and remove leading WS # $value =~ s/from\s*//; $value =~ s/accept\s*//; $value =~ s/[aA][sS]/AS/g; $value =~ s/^\s+//; # # split the line up into AS, lid, rid, cost and the policy # local($as, $lid, $rid, $pref, $pol) = split(/\s+/,$value, 5); if (!&isasnum($as)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\"\n\tneigbour peer". " $as doesn't look like an AS"; } if (!&isipaddr($lid) || !&isipaddr($rid)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\"\n\tip address error"; } if (!$pref) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\"\nyou must give a cost"; } if ($pref !~ /^\(pref=(\S+)\)$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\" preferece is invalid"; } if ($1 ne "MED" && $1 !~ /^\d+$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\"". "\n\t value \"$1\" is invalid"; } if (!$pol) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\"\n\tno ". "routing policy expression given"; } # # now check equal brackets and braces # if(!&isbracket($pol)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: peer $as cost $pref\"" . "\n\tunequal brackets \"\(\)\"\n"; } if(!&isbrace($pol)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: peer $as cost $pref\"" . "\n\tunequal braces \"\{\}\"\n"; } # # Now grab the netlist entries and check they are ok # local($tmppol) = $pol; while($tmppol =~ s/(\{[^\}]*\})// ) { if(!&isnetlist($1)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: peer $as cost $pref\"". "\n\tnetlist error $1"; } } # # Now check the actual keywords # while($tmppol =~ s/(\S+)//) { if (!&isaskeyword($1)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: peer $as cost $pref\"\n\t$1 ". "is not a routing policy KEYWORD"; } } return; } # # io - interas-out # if ($key eq "io") { local($gotmet) = 0; local($as, $lib, $rid, $metric, $pol); $value =~ s/to//; $value =~ s/announce//; $value =~ s/[aA][sS]/AS/g; $value =~ s/^\s+//; # # split up into parts # if ($value =~ /metric-out/) { $gotmet = 1; ($as, $lid, $rid, $metric, $pol) = split(/\s+/, $value, 5); } else { ($as, $lid, $rid, $pol) = split(/\s+/, $value, 4); } if (!&isasnum($as)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\" - ". "neigbour peer $as doesn't look like an AS"; } if (!&isipaddr($lid) || !&isipaddr($rid)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\"\n\tip address error"; } if ($gotmet) { if ($metric !~ /^\(metric-out=(\S+)\)$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\"". "\n\t is invalid"; } if ($1 ne "IGP" && $1 !~ /^\d+$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\"". "\n\t value \"$1\" is invalid"; } } if (!$pol) { return $O_ERROR, "syntax error in \"$ATTL{$key}: $value\" - ". "no routing policy expression given"; } # # now check equal brackets and braces # if(!&isbracket($pol)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: peer $as \"" . "\n\tunequal brackets \"\(\)\"\n"; } if(!&isbrace($pol)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: peer $as \"" . "\n\tunequal brackets \"\(\)\"\n"; } # # Now grab the netlist entries and check they are ok # local($tmppol) = $pol; while($tmppol =~ s/(\{[^\}]*\})// ) { if(!&isnetlist($1)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: peer $as \"". "\n\tnetlist error $1"; } } while($tmppol =~ s/(\S+)//) { if (!&isaskeyword($1)) { return $O_ERROR, "syntax error in \"$ATTL{$key}: peer $as \"". "\n\t$1 is not a routing policy KEYWORD"; } } $object{$key} =~ s/[aA][sS]/AS/g; return; } # # This is simple for now. TB # Will change the isnetnum routine to return various codes and modified # netnum. # in - inetnum # if ($key eq "in") { $j = 0; local($onenet) = 0; @nets = split(/\s+/, $value); if ($#nets == 0) { # check the single network $onenet = 1; $add[0] = $nets[0]; } elsif ($#nets == 2 && $nets[1] == "-") { $add[0] = $nets[0]; $add[1] = $nets[2]; } elsif ($#nets == 1 ) { $add[0] = $nets[0]; $add[1] = $nets[1]; $mod = 1; } else { return $O_ERROR, "syntax error in \"$ATTL{$key}\" - illegal network $value\n"; } foreach $j (0..$#add) { if (!&isnetnum($add[$j])) { return $O_ERROR, "syntax error in \"$ATTL{$key}\" - ". "illegal network \"$add[$j]\"\n"; } } if(!$onenet && (&quad2int($add[1])) < (&quad2int($add[0]))) { return $O_ERROR, "error in \"$ATTL{$key}\" - range is illegal ". "- end of block is too low\n"; } if($mod) { $new = $add[0]." - ".$add[1]; $object{$key} = $new; return $O_WARNING, "\"$ATTL{$key}\" value ". "\"$value\" changed to \"$new\"\n"; } if(!$onenet) { $new = $add[0]." - ".$add[1]; if($new ne $value) { $object{$key} = $new; return $O_WARNING, "\"$ATTL{$key}\" value ". "\"$value\" changed to \"$new\"\n"; } } return; } # # la - localas # if ($key eq "la") { if(!&isasnum($value)) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # lo - location # if ($key eq "lo") { if ($value !~ /^[a-zA-Z0-9\-\.\ \,\(\)\&\'\"\/]+$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # Added this in for now - maybe removed at a later date. # This is MERIT/RA special. # lr - local-route # if ($key eq "lr") { local(@list) = split(/\s+/, $value); if (!&isasnum($list[0])) { return $O_ERROR, "syntax error in \"$ATTL{$key}\" - $list[0] is not a valid peer"; } foreach (1..$#list) { if($list[$_] !~ /^\d+:\d+(\(\d+\))*$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}\" - $list[$_] is invalid"; } } return; } # # ma - maintainer # if ($key eq "ma") { if ($value !~ /^[A-Z0-9\-]+$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # mb - mnt-by # if ($key eq "mb") { if ($value !~ /^[A-Z0-9\-\s+]+$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } # Check whether all mentioned maintainer values are actually # present in the database. This is yucky, but %ExistMaintainer # is sneakily built in GetMaintainer to speed things up.... # As everything, these are only kept per ONE update message (which # can of course have multiple objects ....) local($status) = 0; local($notfound) = ""; foreach (split(/\s+/, $value)) { next if ($ExistMaintainer{$_} || ($value eq $object{"mt"}) || &GetMaintainer($_, $object{"so"})); $notfound .= "$_ "; $status = 1; } return $O_ERROR, "unknown maintainer(s) \"$notfound\" referenced" if $status; return; } # # mt - mntner # if ($key eq "mt") { if ($value !~ /^[A-Z0-9\-]+$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # mn - mnt-nfy # if ($key eq "mn") { if (!&isemail($value)) { return $O_ERROR, "syntax error in \"$ATTL{$key}\" ". "- \"$value\" is not in \(RFC822\) format"; } return; } # # na - netname OR aa - as-name # if ($key eq "na" || $key eq "aa") { local($cur) = $value; local($changed) = 1 if $object{$key} =~ tr/a-z/A-Z/; local($changed) = 1 if $object{$key} =~ tr/\./\-/; local($changed) = 1 if $object{$key} =~ tr/\_/\-/; if ($object{$key} !~ /^[A-Z0-9][A-Z0-9\-]+$/) { $object{$key} = $cur; return $O_ERROR, "illegal $ATTL{$key} \"$cur\""; } else { if ($changed) { $value = $object{$key}; return $O_WARNING, "\"$cur\" changed to \"$value\""; } } return; } # # Will need to change when the NIC-handle syntax is fixed. # # nh - nic-hdl # if ($key eq "nh") { local($uppercased) = 0; if ($DOHANDLE) { if ($value =~ /^[Aa][Ss][Ss][Ii][Gg][Nn]\s*(.*)$/) { if ($1) { if (!&ishandle($1)) { return $O_ERROR, "syntax error in requested nichandle"; } } return; } } if ($object{$key} =~ tr/a-z/A-Z/) { $value = $object{$key}; $uppercased = 1; } if (!&ishandle($value)) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } if ($uppercased) { return $O_WARNING, "\"$ATTL{$key}\" value uppercased"; } return; } # # ni - nsf-in # if ($key eq "ni") { if ($value !~ /^[(\d=\d+)\s*]+$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # no - nsf-out # if ($key eq "no") { if ($value !~ /^[(\d=\d+)\s*]+$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # ns - nserver # if ($key eq "ns") { @list = (); @list = split(/\s+/,$value); $j = 0; foreach $j (0..$#list) { if (!&isdomname($list[$j])) { if ($list[$j] !~ /^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$/) { return $O_ERROR, "illegal nameserver in \"$ATTL{$key}\" ". "component \"$list[$j]\""; } } } return; } # # ny - notify # if ($key eq "ny") { if (!&isemail($value)) { return $O_ERROR, "syntax error in \"$ATTL{$key}\" - ". "\"$value\" is not in \(RFC822\) format"; } return; } # # op - op-phone # of - op-fa # ph - phone # fx - fax-no # if (($key eq "op") || ($key eq "of") || ($key eq "ph") || ($key eq "fx")) { if (!(&isphone($value))) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # om - op-mail # if ($key eq "om") { if (!(&isemail($value))) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # or - origin # if ($key eq "or") { $value =~ tr/a-z/A-Z/; if (!&isasnum($value)) { return $O_ERROR, "syntax error in \"$ATTL{$key}\" - $value is not a valid AS"; } if (($object{$key} =~ tr/a-z/A-Z/)) { return $O_WARNING, "\"$ATTL{$key}\" value uppercased"; } return; } # # pe - peer # if ($key eq "pe") { local(@peer) = split(/\s+/, $value); if($value =~ /localas/) { if($peer[3] ne "localas" || !&isasnum($peer[4])) { return $O_ERROR, "syntax error in \"$ATTL{$key}\"". " - localas error for $value"; } } elsif (!&isipaddr($peer[0]) || !&isasnum($peer[1]) || !&ispeerkeyword($peer[2]) ) { return $O_ERROR, "syntax error in \"$ATTL{$key}\" - $value"; } return; } # # pn - person # if ($key eq "pn") { local(@names) = split(/\s+/, $value); if ($#names == 0) { return $O_ERROR, "syntax error in \"$ATTL{$key}\" - ". "must contain at least two components"; } foreach $j (0..$#names) { if (!&isname($j)) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } } return; } # # rl - routpr-l # if ($key eq "rl") { if ($value !~ /^[A-Z0-9\-\ ]+$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # rm - remarks # if ($key eq "rm") { if ($value !~ /^.*$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # rp - rout-pr # if ($key eq "rp") { if ($value !~ /^[A-Z0-9\-]+$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # rt - route # # A little messy - all the work is done in net2net.pl # if ($key eq "rt") { local($i) = 0; local($NETMASK) = "[nN]*[eE]*[tT]*[mM][aA][sS][kK]"; local($HEX) = "[0-9a-fA-F]"; local($HEXMASK) = "0x$HEX$HEX$HEX$HEX$HEX$HEX$HEX$HEX"; local($IPADDR) = "\\d+\\.\\d+\\.\\d+\\.\\d+"; if ($value =~ /^$IPADDR$/) { local($stat, $msg, @str) = &clasfn_to_netpre($value); if($stat == $NOK) { return $O_ERROR, "$msg\n"; } else { $object{$key} = $str[0]; return $O_WARNING, "$ATTL{$key} re-written to $str[0] from $value\n"; } } elsif ($value =~ /^$IPADDR\s+\-\s+$IPADDR$/) { local($stat, $msg, @str) = &clasfr_to_netpre($value); if($stat == $NOK) { return $O_ERROR, "$msg\n"; } else { if($#str >= 1) { $msg = "$value is not CIDR aligned\n". "resubmit the following seperate objects\n"; foreach $i (0..$#str) { $msg .= "$str[$i]\n"; } return $O_ERROR, "$msg\n"; } else { $object{$key} = $str[0]; return $O_WARNING, "$ATTL{$key} re-written to $str[0] from $value\n"; } } } elsif ($value =~ /^$IPADDR\s+($NETMASK)*\s*$IPADDR$/ || $value =~/^$IPADDR\s+($NETMASK)*\s*$HEXMASK$/) { local($stat, $msg, @str) = &netmask_to_netpre($value); if($stat == $NOK) { return $O_ERROR, "$msg\n"; } else { $object{$key} = $str[0]; return $O_WARNING, "$ATTL{$key} \"$value\" re-written to $str[0] from $value\n"; } } else { local($stat, $msg, @str) = &netpre_verify($value); if($stat == $NOK) { return $O_ERROR, "$msg\n"; } } return; } # # Need to really check against the DNS eventually # # rz - rev-srv # if ($key eq "rz") { @list = (); @list = split(/\s+/,$value); $j = 0; foreach $j (0..$#list) { if (!&isdomname($list[$j])) { return $O_ERROR, "illegal nameserver in $value"; } } return; } # # sd - sub-dom # if ($key eq "sd") { if ($value !~ /^[a-zA-Z0-9\-\ ]+$/) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # so - source # if ($key eq "so") { if (!$DBFILE{$value}) { return $O_ERROR, "unknown source \"$value\""; } if (!$CANUPD{$value}) { return $O_ERROR, "cannot update entry with source \"$value\""; } return; } # # tc - tech-c # if ($key eq "tc") { if (!&isname($value)) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # tr - as-transit # if ($key eq "tr") { return; } # # wd - withdrawn # if ($key eq "wd") { if($value !~ /^(\d\d)(\d\d)(\d\d)$/) { return $O_ERROR, "date part of \"$ATTL{$key}\" not in YYMMDD format"; } # 1988 is the start of the world. This is where we test for proper # date values of YYMMDD if (($1 < 88) || ($2 > 12) || ($3 > 31)) { return $O_ERROR, "date part of \"$ATTL{$key}\" is not a valid YYMMDD value"; } local($s, $m, $h, $md, $mo, $y) = localtime(time); $mo += 1; $md = "0".$md unless $md > 9; $mo = "0".$mo unless $mo > 9; $y = "0".$y unless $y > 9; local($curdate) = "$y$mo$md"; if ($value gt $curdate) { return $O_ERORR, "date in \"$ATTL{$key}\" ($date) is in the future"; } return; } # # zc - zone-c # if ($key eq "zc") { if (!&isname($value)) { return $O_ERROR, "syntax error in \"$ATTL{$key}\""; } return; } # # These are not checked and not used, just in here for clarity # # # ue - *ERROR* # if ($key eq "ue") { return; } # # uf - u-from (NOT USED) # if ($key eq "uf") { return; } # # ui - msg-id (NOT USED) # if ($key eq "ui") { return; } # # uw - WARNING # if ($key eq "uw") { return; } } 1; -------- Logged at Thu Nov 17 16:02:18 MET 1994 --------- From Marten.Terpstra at ripe.net Thu Nov 17 16:01:33 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Thu, 17 Nov 1994 16:01:33 +0100 Subject: cool stuff In-Reply-To: Your message of Wed, 16 Nov 1994 10:32:18 PST. <199411161832.AA05648@chl.isi.edu> Message-ID: <9411171501.AA26328@ncc.ripe.net> cengiz at ISI.EDU (Cengiz Alaettinoglu) writes * Very cool indeed. Is new prtraceroute released? May I get a copy? Here is the latest. Not yet a real release but sort of works I guess. The structure may seem a bit weird, but that is because I automatically include some files that are elsewhere to make a distribution. So never mind all the "1;" and RCS headers everywhere.... Of course the documentation is not updated ;-) The policy parsing bits are in routine isnexthop. Enjoy, -Marten #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh prtraceroute.pl <<'END_OF_prtraceroute.pl' X#!PERL X# X# X# Copyright (c) 1993, 1994 The RARE Association X# X# All Rights Reserved X# X# Permission to use, copy, modify, and distribute this software and its X# documentation for any purpose and without fee is hereby granted, X# provided that the above copyright notice appear in all copies and that X# both that copyright notice and this permission notice appear in X# supporting documentation, and that the name of the author not be X# used in advertising or publicity pertaining to distribution of the X# software without specific, written prior permission. X# X# THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING X# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL X# AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY X# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN X# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF X# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X# X# X# X# $RCSfile: prtraceroute.pl,v $ X# $Revision: 1.1 $ X# $Author: marten $ X# $Date: 1994/10/03 10:11:47 $ X# X# X# This program will do a normal traceroute, and will add some AS info to X# the output, and will compare the real output with what is in the X# database concerning routing policies. X# X# This version has a built in RIPE whois client, just to avoid compatibility X# problems. The default host to query is whois.ripe.net, if you have a RIPE X# whois server closer to home, change the variable WHOISHOST in the Makefile. X# Please note that a query to a non RIPE whois server makes no sense X# whatsoever, besides you may get some nice errors because of special flags X# used. X# Xrequire "getopts.pl"; X X# Temporary for new library X# @INC = (@INC, "/ncc/pride/lib"); X# require "whois.pl"; X# require "nexthops.pl"; X# require "misc.pl"; X X# $RCSfile: whois.pl,v $ X# $Revision: 1.1 $ X# $Author: marten $ X# $Date: 1994/03/02 15:40:14 $ X X# whois.pl - open whois connection, and returns socket descriptor. X# X# Local whois client, to avoid forks and compatibility problems X# It basically is a fully-fledged RIPE version of the whois client. X# It leaves the socket descriptor open, the routine reading from the X# socket is supposed to close the socket again. Besides, the server X# will most probably close the connection, once all data has been output X X# $whoishost = "bwhois.ripe.net"; X# $fast = 1; X Xsub whois { X X local($string) = @_; X X# print STDERR "QUERY: $string\n"; X local($key) = ""; X $port = 43; X $AF_INET = 2; X $SOCK_STREAM = 1; X local($type); X X if (!$connected) { X $sockaddr = 'S n a4 x8'; X ($name, $aliases, $type, $len, $thataddr) = gethostbyname($whoishost); X $that = pack($sockaddr, $AF_INET, $port, $thataddr); X socket(S, $AF_INET, $SOCK_STREAM, $proto) || die "socket failed\n"; X if ( connect(S, $that) ) { X if ( $opt_d) { X printf "** connecting to whois host %s\n", $whoishost; X } X if ($keepopen) { X $connected = 1; X } X } else { X die "Connect to whois host $whoishost failed\n"; X } X if ( $opt_d ) { X printf "** connected ok\n"; X } X } X select(S); $| = 1; select(STDOUT); X X if ($string =~ /^-a/) { X ($tmp, $key) = split(/[\t\s]+/,$string, 2); X print S "-a "; X } X else { X $key = $string; X } X if($keepopen) { X print S "-k "; X } X if($fast) { X print S "-F "; X } X X if($version) { X printf S "-Vpt%s ", $versionno; X } X print S "-r $key\n"; X return S; X} X X1; X# $RCSfile$ X# $Revision$ X# $Author$ X# $Date$ X# X# netinfo.pl - do all stuff needed to read as network information X X#require "whois.pl"; X#require "misc.pl"; X Xsub netinfo { X X local($host) = @_; X X print STDERR "netinfo - called for $host\n" if $opt_d; X X local($netint) = &quad2int($host); X local($net)=$host; X X if (!$donenet{$net}) { X print STDERR "netinfo for $net not yet done\n" if $opt_d; X eval "\%net$netint = &getnetinfo(\"$net\");"; X $donenet{$net} = "net$netint"; X } X eval "\*cur = \*$donenet{$net};"; X X print STDERR "\$cur{\"rt\"} = $cur{\"rt\"}\n" if $opt_d; X return *cur; X} X Xsub getnetinfo { X X local($net) = @_; X local(%en) = (); X local($gotpol) = 0; X local($haveaninetnum) = 0; X local($newline) = 0; X X &whois("-a -T in -T rt -T ir $net"); X X while () { X X# print STDERR "NETINFO Read: $_"; X X chop; X X if ($keepopen) { X if (/^\s*$/) { X last if $newline == 1; X $newline = 1; X next; X } X $newline = 0; X } X # Backward compatibility options. First an inetnum should come out X # then a route if it exists. The route values will always overwrite X # the inetnum values ... X X if (/^inetnum:\s+(.*)$/ || /^\*in:\s+(.*)$/) { X $haveaninetnum = 1; X $en{"rt"} = $1; X next; X } X X if (/^aut-sys:\s+(.*)$/ || /^\*as:\s+(.*)/) { X $en{"or"} = $1; X $gotpol = 1; X next; X } X X if (/^comm-list:\s+(.*)$/ || /^\*cl:\s+(.*)/) { X $en{"cl"} .= " " if $en{"cl"}; X $en{"cl"} .= $1; X $gotpol = 1; X next; X } X X if (/^ias\-int:\s+(\S+)\s+(\S+)/ || /^\*ii:\s+(\S+)\s+(\S+)/) { X $en{$1} = $2; X $dmz{$en{"rt"}} = 1; X $dmzas{"$en{\"rt\"}%$2"} = 1; X $dmzas{"$en{\"rt\"}%$en{\"or\"}"} = 1; X $gotpol = 1; X next; X } X X if (/^route:\s+(.*)$/ || /^\*rt:\s+(.*)$/) { X $en{"rt"} = $1; X next; X } X X if (/^origin:\s+(.*)$/ || /^\*or:\s+(.*)/) { X $en{"or"} = $1; X $gotpol = 1; X next; X } X X if (/^comm-list:\s+(.*)$/ || /^\*cl:\s+(.*)/) { X $en{"cl"} .= " " if $en{"cl"}; X $en{"cl"} .= $1; X $gotpol = 1; X next; X } X if (/^remarks:\s+ias\-int:\s+(\S+)\s+(\S+)/ || X /^\*rm:\s+ias\-int:\s+(\S+)\s+(\S+)/) { X $en{$1} = $2; X $dmz{$en{"rt"}} = 1; X $dmzas{"$en{\"rt\"}%$2"} = 1; X $dmzas{"$en{\"rt\"}%$en{\"or\"}"} = 1; X $gotpol = 1; X next; X } X X if (/^\inet\-rtr:\s+(.*)$/ || /^\*ir:\s+(.*)$/) { X next; X } X if (/^localas:\s+(.*)$/ || /^\*la:\s+(.*)$/) { X $en{"or"} = $1; X $gotpol = 1; X next; X } X X if (/^\s*$/ && $gotpol) { X next; X } X } X return %en; X} X X1; X# $RCSfile$ X# $Revision$ X# $Author$ X# $Date$ X# X# asinfo.pl - do all stuff needed to read as information X X# require "whois.pl"; X Xsub asinfo { X X local($as) = @_; X X if (!$doneas{$as}) { X eval "\%AS$as = &getinfo($as);"; X $doneas{$as} = "AS$as"; X } X eval "\*cur = \*$doneas{$as};"; X X return *cur; X} X Xsub getinfo { X X local($as) = @_; X local(%en) = (); X local($gotpol) = 0; X local($newline) = 0; X X &whois("-a -T an $as"); X X while () { X# print STDERR "AS INFO Read: $_"; X chop; X X if ($keepopen) { X if (/^\s*$/) { X last if $newline == 1; X $newline = 1; X next; X } X $newline = 0; X } X X if (/^aut-num:\s+(.*)$/ || /^\*an:\s+(.*)/) { X $en{"an"} .= "\n" if $en{"an"}; X $en{"an"} .= $1; X next; X } X X if (/^default:\s+(.*)$/ || /^\*df:\s+(.*)/) { X $en{"df"} .= "\n" if $en{"df"}; X $en{"df"} .= $1; X next; X } X X if (/^as\-in:\s+(.*)$/ || /^\*ai:\s+(.*)/) { X ($peer, $weight, $policy) = split(/\s+/, $1, 3); X if (($peer eq $prevpeer) && ($weight eq $prevweight)) { X $en{"ai"} .= " $policy"; X } else { X $en{"ai"} .= "\n" if $en{"ai"}; X $en{"ai"} .= "$peer $weight $policy"; X } X $prevpeer = $peer; X $prevweight = $weight; X $gotpol = 1; X next; X } X X if (/^as\-out:\s+(.*)$/ || /^\*ao:\s+(.*)/) { X $en{"ao"} .= "\n" if $en{"ao"}; X $en{"ao"} .= $1; X next; X } X X if (/^descr:\s+(.*)$/ || /^\*de:\s+(.*)/) { X $en{"de"} = $1 if !$en{"de"}; X next; X } X X if (/^\s*$/ && $gotpol) { X next; X } X } X X $en{"de"} = "??" if !$en{"de"}; X X return %en; X} X X1; Xsub expandmacro { X local($macro) = @_; X local($result); X local($newline) = 0; X X if ($asmacroknown{$macro}) { X return $asmacroknown{$macro}; X } X X &whois("-T am $macro"); X X while () { X# print STDERR "MACRO Read: $_"; X if ($keepopen) { X if (/^\s*$/) { X last if $newline == 1; X $newline++; X next; X } X $newline = 0; X } X if (/^as\-list:\s+(.*)$|^\*al:\s+(.*)$/) { X local($value) = $1; X $value = $2 unless $value; X foreach (split(/\s+/, $value)) { X if ($result) { X $result .= " OR "; X } X if (/^AS\-/) { X $result .= &expandmacro($_); X } else { X $result .= $_; X } X } X next; X } X } X $asmacroknown{$macro} = "( $result ) "; X# print STDERR "Total for $macro is ( $result )\n"; X return "( $result ) "; X} X Xsub quad2int { X local($quad) = @_; X local(@quads); X local($i, $j, $result); X X @quads = split(/\./, $quad); X X $result = 0; X for ($i=0; $i<4; $i++) { X $j = $quads[$i]; X ($j>=0&&$j<256) || die "quad2int: illegal ip number '$quad'\n"; X $result += ($j<<(8*(3-$i))); X } X return $result; X} X Xsub int2quad { X local($int) = @_; X local($i, $j, $result); X X $result = ""; X for ($i=3; $i>=0; $i--) { X $j = ($int>>($i*8))&0xff; X $result = $result . "$j."; X } X chop($result); X return $result; X} X X1; X# $RCSfile$ X# $Revision$ X# $Author$ X# $Date$ X# X# isnexthop - takes a ripe-81 expression, and target values for X# AS and communities (AS in a scalar, communities in a normal array) X Xsub isnexthop { X X local(*ripe81expr, *targetAS, *targetCOM, *targetPrefix) = @_; X local($KEYWORDS) = 'NOT|OR|AND|\(|\)|\{|\}'; X local($newexpr, $expr); X local(@matches) = ($targetPrefix, @targetCOM, $targetAS, "ANY"); X X# print STDERR "Targets: $targetAS, $targetPrefix, ", @targetCOM, "\n"; X X $ripe81expr =~ s:(\(|\)|\{|\}): \1 :g; X X local(@blah) = split(/\s+/, $ripe81expr); X X foreach $i (0..$#blah-1) { X next if $blah[$i] =~ /^$KEYWORDS$/; X next if $blah[$i+1] =~ /^$KEYWORDS$/; X $blah[$i] .= " OR"; X } X for $i (0..$#blah) { X if ($blah[$i] =~ /^AS\-[A-Z0-9]+/) { X splice(@blah, $i, 1, &expandmacro($blah[$i])); X } X $newexpr .= $blah[$i]." "; X } X X# print STDERR "evaluating $newexpr now\n"; X foreach $i (split(/\s+|$/, $newexpr)) { X X next if $i eq ""; X X if ($i eq "NOT") { X $expr .= "!"; X next; X } X if ($i eq "AND") { X $expr .= "&"; X next; X } X if ($i eq "OR") { X $expr .= "|"; X next; X } X if ($i eq "(") { X $expr .= "("; X next; X } X if ($i eq ")") { X $expr .= ")"; X next; X } X if (($i eq "{")) { X $expr .= "("; X next; X } X if ($i eq "}") { X $expr .= ")"; X next; X } X if ($i eq ",") { X next; X } X X foreach $j (@matches) { X if ($i eq $j) { X $expr .= "1"; X $found = 1; X last; X } X } X if (!$found) { X $expr .= "0"; X } X $found = 0; X } X local($result) = eval "$expr;"; X# print "$ripe81expr -> ", $result ? "Y" : "N", "\n"; X return eval "$expr;"; X} X X1; X X# $RCSfile$ X# $Revision$ X# $Author$ X# $Date$ X# X# nexthops.pl - find all nexthops, takes as input an AS number and a X# target host address. Looks up info for these two if needed. Returns X# a string with all nexthops space weight, seperated by %. X X# require "asinfo.pl"; X# require "netinfo.pl"; X# require "isnexthop.pl"; X Xsub nexthops { X X local($as, $target) = @_; X local(@nexthop) = (); X X print STDERR "nexthops - called with ($as, $target)\n" if $opt_d; X X *asen = &asinfo($as); X *neten = &netinfo($target); X X local($targetas) = $neten{"or"}; X local(@targetcom) = split(/\s+/, $neten{"cl"}); X local($targetprefix) = $neten{"rt"}; X X print STDERR "nexthops got all main info, looking at policy now\n" if $opt_d; X foreach (split(/\n/, $asen{"ai"})) { X local($peer, $weight, $policy) = split(/\s+/, $_, 3); X if (&isnexthop(*policy, *targetas, *targetcom, *targetprefix)) { X $nexthop[$index++] = "$weight $peer"; X } X } X if ($asen{"df"}) { X foreach (split(/\n/, $asen{"df"})) { X local($peer, $weight) = split(/\s+/, $_); X $weight+=1000; X $nexthop[$index++] = "$weight $peer (D)"; X } X } X X X# foreach (sort numerically @nexthop) { X# print STDERR "$_\n"; X# } X return sort numerically @nexthop; X} X X1; X X# &nexthops($ARGV[0], $ARGV[1]); X X#print "next hops for $ARGV[1] from $ARGV[0] are:\n"; X#for $i (sort numerically @nexthop) { X# print "$i\n"; X#} X X X X X# This is a associative array used for netinfo. Must be used globally. X X%neti = (); X%asi = (); X X# X$whoishost = "WHOISHOST"; X$traceroutecmd = "TRACEROUTE"; X$hostcmd = "HOSTCMD"; X$keepopen = "KEEPOPEN"; X$fast = "FAST"; X$version = "VERSION"; X$port = PORT; X$AF_INET = 2; X$SOCK_STREAM = SOCKSTREAM; X# X&Getopts('vdlm:q:w:h:p:g:KFV'); X# X$usage="Usage: $0 [-v] [-l] host\nOther: [-d] [-m maxhops] [-q nqueries] [-w waittime] [-g gateway]\n [-h whoishost] [-p port]"; X Xif ($#ARGV != 0) { X print STDERR "$usage\n"; X exit 1; X} X Xif ($ENV{"PRIDEHOST"}) { X $whoishost = &getfqdn($ENV{"PRIDEHOST"}); X} Xif ($opt_h) { X $whoishost = &getfqdn($opt_h); X} Xif ($ENV{"PRIDEPORT"}) { X $port = $ENV{"PRIDEPORT"}; X} Xif ($opt_p) { X $port = $opt_p; X} X Xif ($opt_m) { X $maxhops = $opt_m; X $traceroutecmd = $traceroutecmd." -m ".$maxhops; X} X Xif ($opt_q) { X $queries = $opt_q; X $traceroutecmd = $traceroutecmd." -q ".$queries; X} X Xif ($opt_w) { X $waittime = $opt_w; X $traceroutecmd = $traceroutecmd." -w ".$waittime; X} X Xif ($opt_g) { X $viahost = &getfqdn($opt_g); X $traceroutecmd = $traceroutecmd." -g "."$opt_g"; X} Xif ($keepopen =~ /^TRUE$/) { X $keepopen = 1; X} else { X $keepopen = 0; X} Xif ($opt_K) { X $keepopen = 0; X} Xif ($fast =~ /^TRUE$/) { X $fast = 1; X} else { X $fast = 0; X} Xif ($opt_F) { X $fast = 0; X} Xif ($version=~ /^TRUE$/ ) { X $versionno = "\$Revision: 1.1 $"; #" Need to fool emacs with this quote X $versionno =~ s/\$Revision\: //; X $versionno =~ s/ \$$//; X $version = 1; X} else { X $version = 0; X} Xif ($opt_V) { X $version = 0; X} X X Xif ($opt_d) { X printf "** %s use keepopen feature\n", X $keepopen ? "will" : "will not" ; X} X X X# Needed for sorting things numerically in stead of alphabetically X Xsub numerically { $a <=> $b ; } X X X# X# Return the UTC time for verbose output X# Xsub gettime { X X ($s, $m, $h, $md, $mo, $y, $wd, $yd, $is) = gmtime(time); X X $thismonth = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec)[$mo]; X X $s = "0".$s unless $s > 9; X $m = "0".$m unless $m > 9; X $h = "0".$h unless $h > 9; X X $date = sprintf("%3s %2d %2s:%2s:%2s UTC", X $thismonth, $md, $h, $m , $s ); X return $date; X X} X# X# Return an IP address from a name. X# Xsub getadr { X local($host) = @_; X local($name, $alias, $addrtype, $length, @addr) = gethostbyname($host); X if (defined($addr[0])) { X local($a, $b, $c, $d) = unpack('C4', $addr[0]); X $addr = $a.".".$b.".".$c.".".$d; X return($addr); X } else { X print STDERR "$0: unknown address for $host\n"; X exit 1; X } X} X# X# Return the fully qualified domain name. X# Xsub getfqdn { X local($host) = @_; X# X# resolve an address first X# X if($host =~ /^(\d+)+\.(\d+)\.(\d+)\.(\d+)$/) { X local($fqdntmp) = pack('C4', $1, $2, $3, $4); X local($name, $alias, $addrtype, $length, @addr) = gethostbyaddr($fqdntmp,2); X if (defined($name)) { X return($name); X } else { X return($host); X } X } X# X# okay then try a name X# X ($name, $alias, $addrtype, $length, @addr) = gethostbyname($host); X X if (!defined($name)) { X print STDERR "$0: unknown host $host\n"; X exit 1; X } X return($name); X} X Xsub isipaddr { X local($addr) = @_; X if($addr =~ /^(\d+)+\.(\d+)\.(\d+)\.(\d+)$/) { X return 1; X } else { X return 0; X } X} X Xif ($opt_d) { X printf "** traceroute command will be \"%s\"\n", $traceroutecmd." ".$ARGV[0]; X} X X$destname = &getfqdn($ARGV[0]); X Xopen(TRACE, "$traceroutecmd $ARGV[0] 2>&1|"); X Xwhile () { X X# strip leading spaces, trailing newlines and stars (traceroute timeouts, X# they mess up the ordering of fields, making it impossible to parse) X X s/^[\s\t]+//; X s/\*//g; X chop; X X if (/traceroute: /) { X ($nothing, $error) = split(/:/, $_); X print STDERR "$0: $error\n"; X exit 1; X } X X# First let's find out the AS for the destination network. X X if (/^traceroute/) { # first output line X ($tmp1, $tmp2, $hostname, $net, $rest) = split(/[\s\t]+/, $_); X $net =~ /(\d+\.\d+\.\d+\.\d+)/; X $destnum = $1; X *neti = &netinfo($destnum); X $destnet = $neti{"rt"}; X $das = $neti{"or"}; X if ($neti{$destnum}) { X $das = $neti{$destnum}; X } X if($opt_g) { X if(&isipaddr($opt_g)) { X $viaaddr = $opt_g; X } else { X $viaaddr = &getadr($viahost); X } X *neti = &netinfo($viaadr); X $viaas = $neti{"or"}; X if ($neti{$viaadr}) { X $viaas = $neti{$viaadr}; X } X } X if (!$das) { X print STDERR "** WARNING ** Destination AS unknown ". X "for $hostname \($destnum\)\n"; X $setnopolicy = 1; X } X if ($opt_g && !$viaas) { X print STDERR "** WARNING ** Gateway AS unknown ". X "for $viahost \($viaaddr\)\n"; X $setnopolicy = 1; X } X if ($setnopolicy) { X print STDERR "** WARNING ** Policy information is not ". X "possible - setting to \"?\"\n\n"; X } X X# Try to get the originating AS and other local information. X X local($tmph) = `$hostcmd`; X chop($tmph); X $localhost = &getfqdn($tmph); X $localaddr = &getadr($localhost); X X *neti = &netinfo($localaddr); X $localas = $neti{"or"}; X if ($neti{$localaddr}) { X $localas = $neti{$localaddr}; X } X if ($localas) { X $aspath[++$pathindex] = $localas; X } X if($opt_g) { X $destas = $viaas; X } else { X $destas = $das; X } X if ($opt_v) { X $time = &gettime(); X if (!$localas) { X $localas = "???"; X } X printf "traceroute with AS and policy additions [%s]\n\n", $time; X printf "\t\tfrom %6s %s \(%s\)\n", X $localas ? $localas : "???", $localhost, $localaddr; X if($opt_g) { X printf "\t\tvia %6s %s \(%s\)\n", X $viaas ? $viaas : "???" , &getfqdn($viahost), $viaaddr; X } X printf "\t\tto %6s %s \(%s\)\n\n", X $das ? $das : "???", &getfqdn($hostname), $destnum; X } X else { X printf "traceroute to %s \(%s\) with AS and policy additions\n\n", $hostname, $destnum; X } X next; X } X X# Here come all the hops X X# X# Do something special for first hop. You could be in another AS X# X if (/^1 /) { X $firsthop = 1; X } X X if (/^[0-9]+/) { X X# Get the IP address out of the traceroute output X X ($hop, $hostname, $nettmp, $rest) = split(/[\s\t]+/, $_,4); X $nettmp2 = substr($nettmp, 1); X $netnum = substr($nettmp2, 0, length($nettmp2) - 1); X if ( $firsthop == 1 ) { X $prevas = $localas; X $firsthop = 0; X } else { X $prevas = $as; X } X X# Get the as number for this IP address: X X *neti = &netinfo($netnum); X $as = $neti{"or"}; X X if ($neti{$netnum}) { X $as = $neti{$netnum}; X } X X $lookupnet = $neti{"rt"}; X X X# See if we figure out what kind of routing decision this was according X# to policy in the database X X if (!$as) { X $as = "???"; X } X X if (($as eq $prevas) && ($as !~ /\?/)) { X $type = "I"; X } X elsif ($as =~ /\?/) { X $type = "?"; X } X elsif ($prevas =~ /\?/) { X $type = "?"; X } X else { X @nexthops = &nexthops($prevas, $destnum); X $level = 0; X $cost = 0; X $prevcost = 0; X for $i (0..$#nexthops) { X print "** looking at nexthop $nexthops[$i]\n" if $opt_d; X $prevcost = $cost; X $cost = sprintf("%d", $nexthops[$i]); X if ($prevcost - $cost != 0) { X $level++; X } X if ($nexthops[$i] =~ /$as/) { X print STDERR "$nexthops[$i] matches $as\n" if $opt_d; X if ($nexthops[$i] =~ /\(D\)/) { X $type = "D$level"; X } else { X $type = "E$level"; X } X } X last if $type; X } X X# This is the possible next hop stuff, leave that for a bit later X X if (!$type) { X if (!@nexthops) { X $type = "?"; X } else { X ($tmp, $possas, $tmp) = split(/\s+/, $nexthops[0]); X# $possas =~ s/AS//; X if ($dmzas{"$destnet%$prevas"} && X ($lookupnet eq $destnet)) { X $type = "C"; X } elsif ($dmzas{"$lookupnet%$possas"}) { X local($tmp) = $possas; X# $tmp =~ s/AS//; X if($destas) { X $aspath[++$pathindex] = "[?".$tmp."?]"; X } X &asinfo($tmp); X $type = "?NH $possas"; X } else { X $type = "ERROR"; X } X } X } X } X X if($opt_g && ($as eq $viaas)) { X $as = $viaas; X $destas = $das; X } X } X X X# And print the output X X $rest =~ s/\(\S+\)//g; X $rest =~ s/\s+/ /g; X $icmpmess = $rest; X $icmpmess =~ tr/ ![HPFS]*//cd; X $icmpmess =~ s/\s+$//; X $icmpmess =~ s/\s+/ /g; X $icmpmess =~ s/^\s+//; X if ( $opt_l) { X X# X# Try to do something sensible with this - not too easy as traceroute can X# give very unpredictable results X# This is only really a first stab for those wanting a possibilty to see RTT's X# May try better with this later. X# X $rest =~ s/ \![HPFS]//g; X $rest =~ s/ ms//g; X $rest =~ s/(\S)\s*$/$1 ms/; X printf "%2d %6s %-30s %-18s %s %s%s\n", X $hop, $as, substr($hostname,0,30), $netnum, X $setnopolicy ? "[?]" : "[".$type."]", $rest, X $icmpmess ? " $icmpmess" : ""; X $rest = ""; X } else { X printf "%2d %6s %-30s %-18s %s%s\n", X $hop, $as, substr($hostname,0,30), $netnum, X $setnopolicy ? "[?]" : "[".$type."]", X $icmpmess ? " $icmpmess" : "" ; X } X $type = ""; X $icmpmess = ""; X X# Update the path X X if ($as ne $prevas) { X $aspath[++$pathindex] = "$as"; X } X} X X# End of traceroute output X Xclose(TRACE); X Xprint STDERR "closed trace and whois output now\n" if $opt_d; X# Print path, legend and whois stats X Xif ($#aspath >= 1) { X print "\nAS Path followed: @aspath\n\n"; X for $i (1..$#aspath) { X if ($aspath[$i] ne "???") { X if ($aspath[$i] =~ m/\[.(\S+).]/) { X $aspath[$i] = $1; X } X if (!$done{$aspath[$i]}) { X *asi = &asinfo($aspath[$i]); X printf "%6s = %s\n", X $aspath[$i], $asi{"de"}, X $done{$aspath[$i]} = 1; X } X } X } X} Xclose(S); X X# X# Give some debug stats for those who like this sort of thing X# Xif ($opt_d) { X printf "\n** (needed %d whois queries - %d network, %d asnumbers)\n", X $netwhoisq+$aswhoisq,$netwhoisq, $aswhoisq; X} END_OF_prtraceroute.pl if test 22443 -ne `wc -c hostname.c <<'END_OF_hostname.c' X/* X * X * $RCSfile: hostname.c,v $ X * $Revision: 0.11 $ X * $Author: tony $ X * $Date: 1993/11/16 15:08:24 $ X * X * Super simple hostname command. do a "man gethostname" X */ X#include X Xmain() X{ X char hostname[64]; /* that's what sys/param.h says */ X X if (gethostname(hostname, sizeof(hostname))) { X perror("gethostname"); X exit(-1); X } X puts(hostname); X exit(0); X} END_OF_hostname.c if test 377 -ne `wc -c prtraceroute.8 <<'END_OF_prtraceroute.8' X.\" X.\" X.\" Copyright (c) 1993 The RARE Association X.\" X.\" All Rights Reserved X.\" X.\" Permission to use, copy, modify, and distribute this software and its X.\" documentation for any purpose and without fee is hereby granted, X.\" provided that the above copyright notice appear in all copies and that X.\" both that copyright notice and this permission notice appear in X.\" supporting documentation, and that the name of the author not be X.\" used in advertising or publicity pertaining to distribution of the X.\" software without specific, written prior permission. X.\" X.\" THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING X.\" ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL X.\" AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY X.\" DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN X.\" AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF X.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X.\" X.\" $RCSfile: prtraceroute.8,v $ X.\" $Revision: 0.18 $ X.\" $Author: tony $ X.\" $Date: 1994/05/19 13:50:42 $ X.\" X.\" X.\" X.TH prtraceroute 8 "January 5th, 1994" X.UC 6 X.SH NAME Xprtraceroute \- print the route, AS and policy information packets take to a network host X.SH SYNOPSIS X.B prtraceroute X[ X.B \-d X] [ X.B \-l X] [ X.B \-v X] [ X.B \-m Xmaxhops X] [ X.B \-q Xnqueries X] [ X.B \-w Xwaittime X] [ X.B \-g Xgateway X] [ X.B \-p Xport X] [ X.B \-h Xwhoishost X] X.I host X.SH DESCRIPTION XThe Internet is a large and complex aggregation of Xnetwork hardware, connected together by gateways. XTracking the route one's packets follow (or finding the miscreant Xgateway that's discarding your packets) can be difficult. XFor routing purposes the Internet is split into "autonomous systems" X(ASes) which exchange routing information. XThese ASes can register their routing exchanges in a routing registry. X.I Prtraceroute Xis a version of traceroute that presents this routing policy Xinformation together with the real time Xpacket trace obtained from traceroute. It adds AS information to Xthe normal traceroute output, making use of Routing Registry (RR) database Xinformation. It also Xchecks with the RR database to see how the chosen route compares with the Xthe registered routing Xpolicies in the RR database. X.PP XOptions are: X.SH OPTIONS X.TP 6 X.B \-l XPrint out a X.I longform Xoutput including round-trip-times (RTT's) in milliseconds. X.TP X.B \-d XDebug output. Gives additional internal information and should not be Xused for general use. X.TP X.B \-v XVerbose output. This gives additional information including a timestamp Xin UTC plus a summary of where the prtraceroute was initiated from. XThis is useful when including prtraceroute output in fault reports, trouble Xtickets, etc. X.TP X.BI \-m " maxhops" XSet the max time-to-live (max number of hops) used in outgoing probe Xpackets. The default is 30 hops. X.TP X.BI \-q " nqueries" XSet the desired number of probe queries. The default is 3. X.TP X.BI \-w " waittime" XSet the time (in seconds) to wait for a response to a probe (default 3 Xsec.). X.TP X.BI \-g " gateway" XEnable the IP LSRR (Loose Source Record Route) option. XThis is useful for asking how somebody else, at the specified gateway, Xreaches a particular target. It should be noted that many implementations Xdo not output the interface address if they are the gateway. This can cause X\-g to look a little strange. However, this problem also exists in the Xexisting traceroute. X.TP X.BI \-h " whoishost" XSpecify an alternate whois server to the configured one for routing registry X(RR) data. X.TP X.BI \-p " port" XSpecify an alternate port for the RR whois server. X.SH INTERNALS XThe program makes direct use of the X.I traceroute Xprogram and uses this information to check on AS and RR policy Xinformation. It then uses the X.I whois Xprotocol (which is built in) to derive the RR policy information Xfrom the traceroute output. X.SH EXAMPLES XA sample use and output might be: X X.DS L X.nf X.if t .ft C X% prtraceroute ns0.ja.net Xtraceroute to ns0.ja.net (128.86.1.20) with AS and policy additions X X 1 AS1104 hef-router.nikhef.nl (192.87.45.80) [D1] X 2 AS1103 Amsterdam1.router.surfnet.nl (192.16.183.112) [E1] X 3 AS1103 Amsterdam2.router.surfnet.nl (145.41.9.130) [I] X 4 AS2043 amsterdam4.empb.net (193.172.4.17) [E1] X 5 AS2043 london1.empb.net (193.172.4.5) [I] X 6 AS2043 int-gw.ulcc.ac.uk (193.172.27.14) [I] X 7 AS 786 ns0.ja.net (128.86.1.20) [E1] X XAS Path followed: 1104 1103 2043 786 X XAS1104 = NIKHEF-H XAS1103 = SURFnet IP XAS2043 = European Multiprotocol Backbone XAS 786 = The JANET IP Service X.fi X.DE X.PP XHere is an explanation of the output: X X.DS L X.nf X.if t .ft CB X1st field: Traceroute hopcount X2nd : AS number of the network interface of the router X3rd : Domain name of the interface X4th : IP address of the incoming interface X5th : Policies of the step between the previous line and this line X where: X X I = Internal route (hop within the same AS) X Dn = Default route, the nth choice according policy X so D1 would indicate the primary default route, D2 X the secondary default route, etc X En = External route, the nth choice according to policy X C = The next hop was reached by having a connected interface X and not from a specific routing exchange with the peer. X ? = no information. Either the current AS, or the previous X AS is unknown, so we can not do any useful RR tracing. X ?NH ASn = Possibly making use of a next hop obtained from X ASn. X ERROR = hop is not supposed to be taken according to the X RR information. X X.fi X.DE X.PP XAn AS path summary will be given, and a description of all XASes passed (if they are in the RR database). X X.PP XSome other interesting examples: X X.DS C X.nf X.if t .ft C X% prtraceroute jolly.nis.garr.it Xtraceroute to jolly.nis.garr.it (192.12.192.5) with AS and policy additions X X 1 AS1104 hef-router.nikhef.nl (192.87.45.80) [D1] X 2 AS1103 Amsterdam1.router.surfnet.nl (192.16.183.112) [ERROR] X 3 AS1103 Amsterdam2.router.surfnet.nl (145.41.9.130) [I] X 4 AS2043 amsterdam4.empb.net (193.172.4.17) [E1] X 5 AS2043 pisa1.empb.net (193.172.4.23) [I] X 6 AS2043 garr-gw.cnr.it (193.172.21.2) [I] X 7 AS 137 jolly.nis.garr.it (192.12.192.5) [E1] X XAS Path followed: 1104 1103 2043 137 X XAS1104 = NIKHEF-H XAS1103 = SURFnet IP XAS2043 = European Multiprotocol Backbone XAS 137 = GARR X X.fi X.DE X.PP XIn this example, you see an ERROR in the second hop. This is because the Xrouting policy for AS1104 does not show that it is expecting to receive Xroutes for AS137 from peer AS1103. This is probably an oversight in this Xcase and would immediately alert the AS1104 routing policy object Xmaintainer to this fact. X XHere is another interesting example: X X.DS C X.if t .ft C X.nf X% prtraceroute dfnnoc.gmd.de Xtraceroute to dfnnoc.gmd.de (192.88.108.8) with AS and policy additions X X 1 AS1104 hef-router.nikhef.nl (192.87.45.80) [D1] X 2 AS1103 Amsterdam1.router.surfnet.nl (192.16.183.112) [E1] X 3 AS1103 Amsterdam2.router.surfnet.nl (145.41.9.130) [I] X 4 AS2043 amsterdam4.empb.net (193.172.4.17) [E1] X 5 AS2043 duesseldorf1.empb.net (193.172.4.6) [I] X 6 AS ??? 192.129.8.133 (192.129.8.133) [?] X 7 AS1274 dfnvmgate.gmd.de (192.76.246.23) [?] X 8 AS1275 dfnnoc.gmd.de (192.88.108.8) [ERROR] X XAS Path followed: 1104 1103 2043 ??? 1274 1275 X XAS1104 = NIKHEF-H XAS1103 = SURFnet IP XAS2043 = European Multiprotocol Backbone XAS1274 = GMD XAS1275 = GMD-DFN X.fi X.DE X.PP XHere we see a number of unknowns ("?"s). They start at hop 6. The first Xis due to not being able to see what AS network 192.129.8.0 belongs to. This Xhas the added "knock-on" effect of making impossible to tell if the Xrouting is correct for hop 5 to 6 and hop 6 to 7. X X.PP XAn example of the X.I longform Xformat is given: X X.DS C X.nf X.if t .ft C X% prtraceroute -l ns0.ja.net Xtraceroute to ns0.ja.net (193.63.94.20) with AS and policy additions X X 1 AS1104 hef-router.nikhef.nl (192.87.45.80) [D1] 3 3 ms X 2 AS1103 Amsterdam1.router.surfnet.nl (192.16.183.112) [E1] 3 2 ms X 3 AS1103 Amsterdam2.router.surfnet.nl (145.41.9.130) [I] 4 3 ms X 4 AS2043 amsterdam4.empb.net (193.172.4.17) [E1] 6 22 ms X 5 AS2043 london1.empb.net (193.172.4.5) [I] 22 22 ms X 6 AS2043 int-gw.ulcc.ac.uk (193.172.27.14) [I] 23 25 ms X 7 AS 786 ns0.ja.net (193.63.94.20) [E1] 27 40 ms X XAS Path followed: 1104 1103 2043 786 X XAS1104 = NIKHEF-H XAS1103 = SURFnet IP XAS2043 = European Multiprotocol Backbone XAS 786 = The JANET IP Service X X.fi X.DE X.PP XAs you can see RTTs are given after the normal prtraceroute output. Note Xthat this output is somewhat different to the normal traceroute output. XIt should also be noted that using the \-l flag will not always produce Xconsistent results. X.SH ENVIRONMENT X.IP "PRIDEHOST" 8 XThis will change the RR whoishost to use. The \-h option will override this. XThe default is WHOISHOST. X.IP "PRIDEPORT" 8 XThe will change the port number to use to connect to the RR. The \-p port Xwill override this. The default is port XPORT. X.SH LIMITATIONS XIf the destination network is not labeled with an AS number in the RR, the program Xwarns you of this and set the policy information field to unknown as it can't compute Xpolicy information without this information.. XGeneral lack of information in the RR Xdatabase will generate lots of question Xmarks as we have untraceable policies. XNeeds quite a number of whois queries, but never the same information Xtwice. XNeeds good "whois" connectivity to the whois server. X.SH AUTHORS XAll the tricky bits were done by Marten Terpstra with a lot of cosmetic work Xfrom Tony Bates. Daniel Karrenberg helped in the co-development of the idea Xand design for prtraceroute. Of course, none of this would be Xpossible without Van XJacobson's wonderful traceroute program. X.SH BUGS XThe \-l output does not produce consistent results. X.SH SEE ALSO Xwhois(1), perl(1), ping(8), traceroute(8). X.PP X"Representation of IP Routing Policies in the RIPE Database - ripe-81", XTony Bates, Jean-Michel Jouanigot, Daniel Karrenberg, Peter Lothberg, Marten XTerpstra. END_OF_prtraceroute.8 if test 10618 -ne `wc -c Makefile <<'END_OF_Makefile' X# X# X# Copyright (c) 1993 The RARE Association X# X# All Rights Reserved X# X# Permission to use, copy, modify, and distribute this software and its X# documentation for any purpose and without fee is hereby granted, X# provided that the above copyright notice appear in all copies and that X# both that copyright notice and this permission notice appear in X# supporting documentation, and that the name of the author not be X# used in advertising or publicity pertaining to distribution of the X# software without specific, written prior permission. X# X# THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING X# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL X# AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY X# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN X# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF X# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X# X# X# X# $RCSfile: Makefile,v $ X# $Revision: 1.1 $ X# $Author: marten $ X# $Date: 1994/10/03 13:31:02 $ X# X# Makefile for policy routing tools X XSRC= prtraceroute.pl hostname.c XMAN= prtraceroute.8 X X#CC= cc XCC= gcc X# X# Local install stuff XBINDIR= /usr/local/bin XPERL= /usr/local/bin/perl XMANDIR= /usr/local/man XMANEXT= 8 XHOSTCMD= /bin/hostname XTRACEROUTE= traceroute XWHOISHOST= dbase.ripe.net XPORT= 43 X# X# If you are running Solaris 2.* set SOCKSTREAM to 2 X# otherwise leave it as it is X# XSOCKSTREAM= 1 X# XKEEPOPEN= TRUE XFAST= TRUE XVERSION= TRUE XSHAR= shar -odist.shar X XOBJ= prtraceroute XDIST= $(SRC) $(MAN) Makefile README INSTALL CHANGES TODO X Xprtraceroute: prtraceroute.pl Makefile $(DEP) X sed -e 's:WHOISHOST:$(WHOISHOST):' \ X -e 's: PORT: $(PORT):' \ X -e 's:PERL:$(PERL):' \ X -e 's:HOSTCMD:$(HOSTCMD):' \ X -e 's:TRACEROUTE:$(TRACEROUTE):' \ X -e 's:KEEPOPEN:$(KEEPOPEN):' \ X -e 's:SOCKSTREAM:$(SOCKSTREAM):' \ X -e 's:FAST:$(FAST):' \ X -e 's:VERSION:$(VERSION):' \ X < prtraceroute.pl | \ X $(PERL) -e 'while(<>) { chop; s/\s*$$//; next if (/^# #/); if(/(^.*)(# #.*$$)/) { printf "$$1\n"; next; } print "$$_\n"; }' > $@ X chmod 755 $@ X Xlib: prtraceroute.pl.lib X ./parseincludes < prtraceroute.pl.lib > prtraceroute.pl X Xinstall: $(OBJ) Makefile $(MAN) $(DEP) X sed -e 's:WHOISHOST:$(WHOISHOST):' \ X -e 's:XPORT:$(PORT):' $(MAN) > $(MAN).tmp X -install -m 755 $(OBJ) $(BINDIR) X -install -m 644 ${MAN}.tmp ${MANDIR}/man${MANEXT}/${MAN} X -rm $(MAN).tmp X Xhostname: hostname.o X $(CC) $(CFLAGS) -o hostname hostname.o X strip hostname X Xdist.shar: $(DIST) X $(SHAR) $(DIST) X X Xdist: dist.shar X Xall: prtraceroute hostname dist X Xman: $(MAN) X -install -m 644 ${MAN} ${MANDIR}/man${MANEXT}/${MAN} X Xclean: X -rm -f core a.out dist.shar *.o ,* $(OBJ) X X END_OF_Makefile if test 2786 -ne `wc -c README <<'END_OF_README' X# X# $RCSfile: README,v $ X# $Revision: 0.15 $ X# $Author: tony $ X# $Date: 1993/11/26 16:53:18 $ X X THIS IS THE README FOR PRTRACEROUTE X X XINTRODUCTION X X Prtraceroute is part of the PRIDE Tools release. It comes with a X simple installation procedure. It relies on having the following:- X X o perl X o traceroute X X built on your system. X X "perl" and "traceroute" can be obtained from any of the well known X ftp archive sites (preferably somewhere near to you). X X Prtraceroute is a version of traceroute that gives additional routing X policy information. It adds AS information to the normal traceroute X output, making use of Routing Registry (RR) database information. X It also checks with the RR database to see how the chosen route X compares with the the registered routing policies in the RR database. X X For more details look at the manual page. X XINSTALLATION X X See the file "INSTALL" for more details on installing prtraceroute. X X XPORTING ISSUES X X prtraceroute has been tested on both SUNOS and BSDI with various X versions of perl and traceroute without any problems. X prtraceroute uses "hostname". A simple version is supplied if your X system doesn't have this. X XBUG REPORTS, FIXES, COMMENTS AND HELP X X Please report bugs, enhancements and comments to the mailing X list below: X X pride-tools at ripe.net X X Enjoy !!!! END_OF_README if test 1390 -ne `wc -c INSTALL <<'END_OF_INSTALL' X# X# $RCSfile: INSTALL,v $ X# $Revision: 0.16 $ X# $Author: tony $ X# $Date: 1994/04/27 11:10:20 $ X XINSTALL - prtraceroute X XInstallation: X X- Edit the Makefile for X X BINDIR - Installation directory (default: /usr/local/bin) X X HOSTCMD - the hostname command for your system. X (A simple version is supplied which should work X on most platforms - probably not needed anyway). X X KEEPOPEN - Enables or disables keeping the tcp connection X for the built-in whois client. This will only work X with RIPE whoisd. Possible values are TRUE or FALSE. X (default: TRUE as using whois.ripe.net by default). X X MANDIR - Man directory (default: /usr/local/man) X X TRACEROUTE - the traceroute command on your system X (default: traceroute) X X X PERL - the full path of Perl on your system X (default: /usr/local/bin/perl) X X X WHOISHOST - Alternative RIPE whois server X (default: whois.ripe.net) X X PORT - Atlernate port for whois server X (default: 43) X X SOCKSTREAM - value of SOCK_STREAM. The default is 1. X On Solaris 2.* it is 2. If unsure you'll X need to check in sys/socket.h of your X system include files. Normally somewhere like X /usr/include/sys/socket.h and look for the X value of SOCK_STREAM. On most systems (not Solaris X 2.*) this will look like this. X #define SOCK_STREAM 1 /* stream socket */ X X X FAST - Used for getting whois data out of the daemon faster X This will only work the *latest* RIPE whoisd. X Possible values are TRUE or FALSE. X (default: TRUE as using whois.ripe.net by default). X X VERSION - Used for telling the daemon the version number of the X client. This will only work X with RIPE whoisd. Possible values are TRUE or FALSE. X (default: TRUE as using whois.ripe.net by default). X X XType the following: X X"make" - This will install a executable version in the current directory X X"make install" - This will install executable version in BINDIR X X"make clean" - This make clean, including executable versions in current dir X XOptionally: X X"make dist" - This will make a distribution in shar format (requires shar, or X you need to change the SHAR variable in the Makefile) X X"make hostname" - Probably not needed but in case. Makes a very simple version X of hosname. It WILL NOT install it anywhere (this is up to X you). Then edit HOSTCMD (setting it to simple hostname path) X the re-make. END_OF_INSTALL if test 2936 -ne `wc -c CHANGES <<'END_OF_CHANGES' X# X# X# $RCSfile: CHANGES,v $ X# $Revision: 0.15 $ X# $Author: tony $ X# $Date: 1994/04/27 11:10:20 $ X XThis FILE IS NOT UP TO DATE SORRY. X XChanges from the BETA-1 Release X----------------------------- X1. Added in FAST support. X This is needed due to the size of some of the RIPE-81 policy objects. X See AS1755. X X2. Added in VERSION support. X This is used to track the use of PRIDE tools. X X=========== X Xalpha-1.8 X Fixed local variable bug X Xalpha-1.7 X If no destination AS can be found, the program exits X because otherwise the output will be highly unpredictable X Xalpha-1.6 X Fixed silly bug where traceroute put some output on stderr X other on stdout, and the program got confused. X Xalpha-1.5 X RIPE whois client built in to avoid many forks and whois X compatibilty issues. X X All variables that may need to be altered are now in the X Makefile, and make will automatically alter them X X Argument checking, no extra arguments passed to traceroute X most give rubbish output. X X Corrected bug where RIPE whois servers did not return AS X information yet and the output got silly X Xalpha-1.4 X first "usable" release, although never released ;-) END_OF_CHANGES if test 1155 -ne `wc -c TODO <<'END_OF_TODO' X# X# X# X# $RCSfile: TODO,v $ X# $Revision: 1.3 $ X# $Author: marten $ X# $Date: 1994/11/17 14:51:07 $ X XTo be filled in .... END_OF_TODO if test 143 -ne `wc -c Marten, You raise a couple of really good philosophical issues here that probably need some discussion. (On the other hand, I wasn't present for the last round of discussions, so maybe Dale just needs bringing up to speed). I'll try to do one in this message; a simpler one follows separately. > I would like to keep the attributes as they are defined now as they are > and any extra stuff needed should move to new (experimental) > attributes. We can't have a stable set of attributes if we keep > changing the form of them. This will confuse too many people. In this case, I have placed some extra information at the end of an existing attribute (EGP/BGP, and Active/Passive or Default/NonDefault). Assume for the moment that this information really does have to be stored somewhere in order to be able to build configurations from the data. Then there are a few ways we could handle this: 1) Append the information to the existing attribute [as you found in our data now]. This probably violates the published spec (unless it actually doesn't *say* that you can't have any extra parameters at the end). It can confuse people, as you mentioned. But it does supply all of the normal information in a form usable by normal tools. (As you mentioned, prtraceroute is using that information today). 2) Create a parallel experimental attribute that is just like the description above, but which has a different name. Obviously I can generate my config files using that new attribute name. But then we have a decision on whether I should be producing *both* attributes all the time, or just the new experimental one. If I don't produce both, then prtraceroute (and future tools) have just gotten poorer because they have lost access to some valid data. If I do produce both, then everyone's data gets twice as complex. And we still introduce confusion because there is a new named attribute showing up in the GRR data. (And everyone has to support this new attribute in their conf file). 3) Instead of creating an experimental attribute that has all the information, create a different one that has only the new information (e.g. EGP/BGP/IDRP and "which end of the session" markers). Now we still have all the disadvantages of #2 except for the replication of data, and we have a much tougher path to migrate to one sensible combined attribute later. (The code to generate the configs happens to get a bit messier, too; and this messiness means that people will make more mistakes in entering the data). I think that part of the problem comes form having a specification document that was frozen before implementations were built. Mind you, I am *extremely* happy that RIPE-181 was published and exists as a [realatively]? firm target; this has put to bed a lot of previous discussions about which ways of doing things ought to be chosen and allowed coding progress to be made. (And RIPE-122, which specifies the inet-rtr). But we need a method of modifying the document in minor ways to reflect discoveries from implementation experience, and we certainly need the ability to implement experimental changes in advance of formal group acceptance of those changes. Obviously, if the eventual group decision is different than the draft implementation, then the implmentation has to change if possible. The IETF model of "draft standards" is one model--I don't think BGP4 even has an RFC number yet, even though it is the default current standard. RIPE might have a different solution ("draft-ripe-122-experimental-mods"?), but I think *something* is needed. The other half of the question is how to handle such experimental mods in the GRR. We have all ready discovered (I think) that there needs to be close coordination between the internal attribute names of *ALL* of the registries participating in the GRR. (Merit is still sorting out changes based on conf file changes going to 181, and our two new attributes assigned this week need to be put into conf files by all registries that are going to accept RADB or PRDB.db data, which is probably all registries). We could come up with models that strip such experimental information in the transfer process. This would be relatively easy to implement, but it would produce most of the problems listed in the numbered sections above (i.e. useful information would disappear). Or, we could implement a system to give rapid global support for experimental changes: a way to post drafts of experimental changes, and to get support code for those changes (at least conf attribute additions) to all GRR participants. Or some combination. My preference is for rapid support of some extensions that needn't interrupt backward compatibility (e.g. new tokens at the end of an attribute), along with guidelines and support procedures for documenting and integrating those changes into all the registries. Plus other (presumably slower) arrangements for more substantial changes. Eventually, all changes need to go through the group process. But whatever the procedures are or become, it must be possible to build new things quickly, and then to bring discoveries from those implementations into the standards process as they are proven. (Even if this involves filtering the new extensions from the the transfer format files for a while). Grist for the GRR discussions. Thoughts? --Dale =========================================================================== > * > - there are some extra keywords for the peer definition in an inet-rtr > * > which are not ripe-181, what are we going to do with them? Examples: > * > *pe: 144.171.1.254 AS2649 BGP passive > * > *pe: 192.231.238.3 AS2020 EGP def > * > > * > According to the spec, after the protocol indication there can be an > * > optional AS number only .... > * > * Yes, this is problem. I doubt we can generate AS690 configs without > * this information, or that any else can generate their configs without > * it, either. Suggestions? > > Not sure. Perhaps we need some experimental extensions to the inet-rtr > object... You are probably closer to knowing what you want than us. I > would like to keep the attributes as they are defined now as they are > and any extra stuff needed should move to new (experimental) > attributes. We can't have a stable set of attributes if we keep > changing the form of them. This will confuse too many people. > > * > - then the number of AS objects that have no policy information. May > * > of them have fake maintainers, many of them are European, and I > * > personally do not think they should be in the prdb (or rrdb for that > * > matter). > * > * Sounds like a problem for the GRR meeting at the IETF. You don't > * want to throw away the AS-name information just because there isn't any > * policy registered for it, because then prtraceroute etc. become much > * less valuable tools. There should be a good way of picking the "best" > * (or, probably, most authorative) source for data to be used by > * tools. > > Definately yes. Let's take this up at the GRR meeting. > > * Eliminating maintainer objects for which we have no contact information > * has been on my queue for about three hours now; that one will get solved > * when I get some time. > > No problem, all these comments were purely things that I noticed. Now > that we have a real spec in ripe-181, we should try and stick to it. > We should start with a stable set and only after that move on. > > * > What we have done at the NCC is simply place them in their > * > own little database (source NCC-AS-LIST) which is simply generated > * > automatically and provides at least a descr for all unknown ASes in > * > the RR. > * > * How is this different from having these little records in the > * prdb.db? > > Slightly in semantics. The AS list we keep is not part of the routing > registry as such. Again, we should take these issues up with the > general data distribution model. > > * > I think you should only register the AS that have policy info. > * > If not, the RRs have loads of overlapping and possibly inconsistent or > * > differently formatted information which is no good. > * > * Again, refusing to know the name of an AS because they haven't yet > * registered their policy strikes me as a bit self-defeating. Overlapping > * and therefore potentially inconsistent data is probably the central > * problem of the GRR; we have it in a lot more cases than just this. > > In my view (but I can be wrong) it is more what info is in a RR as > opposed to info being used by the tools ... Not a big deal, a data > distribution model should solve these things. > > -Marten > -------- Logged at Thu Nov 17 18:47:31 MET 1994 --------- From dsj at merit.edu Thu Nov 17 18:47:18 1994 From: dsj at merit.edu (Dale S. Johnson) Date: Thu, 17 Nov 1994 12:47:18 -0500 Subject: more on prdb format Message-ID: <199411171747.MAA02157@merit.edu> Marten, > In my view (but I can be wrong) it is more what info is in a RR as > opposed to info being used by the tools ... Not a big deal, a data > distribution model should solve these things. What is the mechanism for a tool to use data which is not in the Registry? What is the definition of "in the registry"? My guess at a definition would be: if the data is available via whois or as part of the ftp version of [database].db, then it is in the registry. And that (as far as possible subject to cron processing constraints) if it is in one place, it should be in both places. [Otherwise someone is going to feel forced and justified in beating up your whois server for everything it knows!] This has been a big issue here with respect to Community implementation. At the moment we have not been released from the responsibility to maintain AUP certification by nets, and to use this list of AUP nets in the generation of config files. (And therefore in policy expressions). Our current implementation of this is to use a special-case community name (COMM_NSFNET), which refers to what was called a "guardian file" under RIPE-81. This bothers me enormously because this means we have policy expressions which cannot be interpreted without recourse to data that is not part of the ftpable version of the database. At the moment, that means that other members of the GRR can't and don't get that "hidden" data. It sounds like you have similar "hidden" data that the tools can get to, but people who write other data crunchers can't? --Dale ========================================================================== > * > What we have done at the NCC is simply place them in their > * > own little database (source NCC-AS-LIST) which is simply generated > * > automatically and provides at least a descr for all unknown ASes in > * > the RR. > * > * How is this different from having these little records in the > * prdb.db? > > Slightly in semantics. The AS list we keep is not part of the routing > registry as such. Again, we should take these issues up with the > general data distribution model. > > * > I think you should only register the AS that have policy info. > * > If not, the RRs have loads of overlapping and possibly inconsistent or > * > differently formatted information which is no good. > * > * Again, refusing to know the name of an AS because they haven't yet > * registered their policy strikes me as a bit self-defeating. Overlapping > * and therefore potentially inconsistent data is probably the central > * problem of the GRR; we have it in a lot more cases than just this. > > In my view (but I can be wrong) it is more what info is in a RR as > opposed to info being used by the tools ... Not a big deal, a data > distribution model should solve these things. > > -Marten > -------- Logged at Mon Nov 21 16:17:37 MET 1994 --------- From dsj at merit.edu Mon Nov 21 16:17:34 1994 From: dsj at merit.edu (Dale S. Johnson) Date: Mon, 21 Nov 1994 10:17:34 -0500 Subject: RWHOIS Bof (conflicts with GRR Meeting) Message-ID: <199411211517.KAA29972@merit.edu> I'm not sure this is work rescheduleing anything for, but this is at the same time as the GRR meeting: > From owner-rwhois at internic.net Fri Nov 18 19:12:41 1994 > From: Mark Kosters > Subject: DECEMBER '94: RWHOIS BOF (fwd) > To: rwhois at internic.net > Date: Fri, 18 Nov 1994 19:06:44 -0500 (EST) > Sender: owner-rwhois at internic.net > > FYI for those who are not apart of the ietf-announce list. > > Mark > > Forwarded message: > > From ietf-announce-request at IETF.CNRI.Reston.VA.US Fri Nov 18 19:00 EST 1994 > > To: IETF-Announce:; > > Sender: ietf-announce-request at IETF.CNRI.Reston.VA.US > > From: Scott Williamson > > Subject: DECEMBER '94: RWHOIS BOF > > Date: Fri, 18 Nov 94 13:45:01 -0500 > > X-Orig-Sender: mwalnut at CNRI.Reston.VA.US > > Message-ID: <9411181345.aa07087 at IETF.CNRI.Reston.VA.US> > > Content-Type: text > > Content-Length: 1203 > > > > > > Group Name: RWHOIS BOF (rwhois) > > IETF Area : User Services AND Operational Requirements > > Date/Time : Monday, December 5, 1994 > > 1930-2200 > > > > =================== > > > > > > RWhois is a simple protocol that allows for distribution of traditional > > NIC-maintained "whois" information. RWhois will work on heirarchical > > information with the idea of if it is not at this site, it can then > > refer the user to a closer site that may have more information. RWhois > > is being developed in response to the ip reassignment problem and > > the general load on current Internet Registry for registrations. > > > > > > I. What RWhois is > > - what it tries to solve > > - Protocol Doc > > - differences between RWhois, whois++, X.500 > > - interaction between whois, whois++, and RWhois > > > > II. Required Object and Attribute Set for NICs > > - SOA Objects > > - Network Objects > > - Domain Objects > > - Host Objects > > - AS Objects > > - Role Account Objects > > - Individual Objects > > > > III. Secondaries > > > > IV. On-Line Editing > > > > V. Discussion of Mimimal Operational Requirements and Deployment > > Schedule > > - InterNIC (NIC for the Americas and Global IR) > > - AP Region > > - European Region > > - US Domain > > > > VI. Discussion if needs a working group > > > > > > > -- > > Mark Kosters markk at internic.net +1 703 742 4795 > Software Engineer InterNIC Registration Services > -------- Logged at Mon Nov 21 18:40:29 MET 1994 --------- From Marten.Terpstra at ripe.net Mon Nov 21 18:32:41 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Mon, 21 Nov 1994 18:32:41 +0100 Subject: database config change Message-ID: <9411211732.AA25530@ncc.ripe.net> Folks, Due to the introduction of or routes and other changes that are a result of the second and final database transition today towards ripe-181, please find below the object definitions as currently used at the NCC. Secondaries should update their config. For others, FYI. Also there are some other variables which will no longer be used: CONNECT, SPLITMSG, GRDCONFLICT. If you have questions, please let me know. -Marten # The list of valid attribute names themselves in short and long version # ATTR ac admin-c ATTR aa as-name ATTR ad address ATTR ae as-exclude ATTR ai as-in ATTR al as-list ATTR an aut-num ATTR am as-macro ATTR ao as-out ATTR as aut-sys ATTR at auth ATTR au authority ATTR av advisory ATTR bg bdry-gw ATTR bi bis ATTR bl bdrygw-l ATTR ch changed ATTR cl comm-list ATTR cm community ATTR co connect ATTR cy country ATTR da dom-name ATTR de descr ATTR df default ATTR di dom-net ATTR dm dom-in ATTR dn domain ATTR do dom-out ATTR dp dom-prefix ATTR dt upd-to ATTR em e-mail ATTR fx fax-no ATTR gd guardian ATTR gw gateway ATTR ho hole ATTR if ifaddr ATTR ii ias-int ATTR in inetnum ATTR ir inet-rtr ATTR it interas-in ATTR io interas-out ATTR la localas ATTR lo location ATTR ma maintainer ATTR mb mnt-by ATTR mt mntner ATTR mn mnt-nfy ATTR na netname ATTR nh nic-hdl ATTR ni nsf-in ATTR no nsf-out ATTR ns nserver ATTR ny notify ATTR op op-phone ATTR of op-fax ATTR om op-mail ATTR or origin ATTR pe peer ATTR ph phone ATTR pn person ATTR rl routpr-l ATTR rm remarks ATTR rp rout-pr ATTR rt route ATTR rz rev-srv ATTR sd sub-dom ATTR so source ATTR tc tech-c ATTR tr as-transit ATTR wd withdrawn ATTR zc zone-c # TEMPORARY FOR MERIT, WILL DISSAPEAR IN APRIL 1995 # Has been renamed to "av" or "advisory" and that one will stay # Keep here for just a little while longer... ATTR lr local-route # Attributes with u* short names are special! # They all have hardcoded side effects, so do NOT change them # unless you know what you are doing ATTR ua authorise # very special ATTR ud delete # delete operation ATTR ue *ERROR* # error attribute ATTR uo override # very special as well ATTR uw WARNING # warning attribute # # attribute aliases (because they appear so often!) # ATTA ch change ATTA em email ATTA fx fax ATTA rm remark ATTA ua authorised ATTA ud deleted ATTA aa asname # object alias for template mode # ALIAS in network ALIAS in netnum # The database objects in terms of their attributes # # ATSQ - all defined attributes in this object, also defines print order # MAND - these attributes are mandatory # OPT - these attributes are optional # MULT - these attributes can appear more than once per object # SORT - sort order, a number, lowest sorted first # UNIQ - these attributes define the unique key # KEYS - these attributes define all possible keys # REC - these attributes must be looked up if referenced # OBS - these attributes are obsoleted and will be removed from objects # The NEED to be in ATSQ though to be recognized # # First, let's determine what objects are guarded, these can not be # updated automatically, and will generate an error message. # These objects need a "mnt-by" attribute or some other magic .... GRDOBJ am an cm rt ir mt # autonomous systems # OBJ an ATSQ an aa de ai ao it io ae df gd ac tc OBJ an ATSQ rm ny mb ch so OBJ an MAND an de ac tc ch so OBJ an OPT aa ai ao it io ae df gd rm ny ma mb OBJ an MULT de ai ao it io ae df ac tc rm ch ny mb OBJ an SORT 0 OBJ an UNIQ an OBJ an KEYS an OBJ an REC ac tc # as macros # OBJ am ATSQ am de al gd tc ac rm ny mb ch so OBJ am MAND am de al gd tc ac ch so OBJ am OPT rm ny OBJ am MULT de al tc ac rm ch ny mb OBJ am SORT 8 OBJ am UNIQ am OBJ am KEYS am OBJ am REC tc ac # boundary gateways - obsoleted 940906 # # OBJ bg ATSQ bg de lo au gd ac tc rm ny ma ch so # OBJ bg MAND ac au bg ch de gd lo so tc # OBJ bg OPT ny ma rm # OBJ bg MULT ac de lo tc ch ny # OBJ bg SORT 1 # OBJ bg UNIQ bg # OBJ bg KEYS bg # OBJ bg REC ac tc # community # OBJ cm ATSQ cm de au gd tc ac rm ny ma mb ch so OBJ cm MAND cm de au gd tc ac ch so OBJ cm OPT ny ma rm OBJ cm MULT de tc ac rm ch ny mb OBJ cm SORT 6 OBJ cm UNIQ cm OBJ cm KEYS cm OBJ cm REC ac tc OBJ cm OBS ma # domains # OBJ dn ATSQ dn de ac tc zc ns sd di rm ny ma mb ch so OBJ dn MAND ac ch de dn so tc zc OBJ dn OPT di ns rm sd ny ma mb OBJ dn MULT ac ch de di ns rm sd tc zc ny mb OBJ dn SORT 4 OBJ dn UNIQ dn OBJ dn KEYS dn OBJ dn REC ac tc zc OBJ dn OBS ma # networks # # Switch above line to below line after a reasonable time after T2 # OBJ in ATSQ in na de cy ac tc rz rm ny ma mb ch so # OBJ in ATSQ in na de cy ac tc co as cl ii ni no gw rz OBJ in ATSQ rm ny ma mb ch so OBJ in MAND ac ch cy de in na so tc OBJ in OPT as bl cl co ch gw ii ni no rl rm rz ny ma mb OBJ in MULT ac ch de ii rm rz tc ny mb OBJ in SORT 5 OBJ in UNIQ in OBJ in KEYS in na OBJ in REC ac tc OBJ in OBS co as cl ii ni no gw bl rl ma # persons # OBJ pn ATSQ pn ad ph fx em nh rm ny ma mb ch so OBJ pn MAND ad ch ph pn so OBJ pn OPT em fx nh rm ny ma mb OBJ pn MULT ad ch em fx ph rm ny mb OBJ pn SORT 3 OBJ pn UNIQ pn nh OBJ pn KEYS pn nh OBJ pn OBS ma # routing privileges - obsoleted 940906 mt # # OBJ rp ATSQ rp de au gd ac tc rm ny ma ch so # OBJ rp MAND ac au ch de gd rp so # OBJ rp OPT tc ny ma # OBJ rp MULT ac de tc ch ny # OBJ rp SORT 2 # OBJ rp UNIQ rp # OBJ rp KEYS rp # OBJ rp REC ac tc # clns object # OBJ dp ATSQ dp da de bi dm do df ac tc gd rm ny ma mb ch so OBJ dp MAND dp da ac tc ch so OBJ dp OPT bi de dm do df gd ny ma rm mb OBJ dp MULT de bi dm do df ac tc ch ny rm mb OBJ dp SORT 7 OBJ dp UNIQ dp OBJ dp KEYS dp da OBJ dp REC ac tc OBJ dp OBS ma # inet-rtr # OBJ ir ATSQ ir la if pe ac tc rm ny mb ch so OBJ ir MAND ir la if tc ac ch so OBJ ir OPT pe ny mb rm OBJ ir MULT if pe tc ac rm ny ch mb OBJ ir SORT 9 OBJ ir UNIQ ir OBJ ir KEYS ir if OBJ ir REC tc ac # maintainer # OBJ mt ATSQ mt de ac tc dt mn at rm ny mb ch so OBJ mt MAND mt de ac dt at ch so OBJ mt OPT tc mn rm ny mb OBJ mt MULT de ac tc dt mn at rm ny mb ch OBJ mt SORT 10 OBJ mt UNIQ mt OBJ mt KEYS mt OBJ mt REC ac tc # route # # lr or local-route should go soon .... # OBJ rt ATSQ rt de or ho wd cl lr av rm ny mb ch so OBJ rt MAND rt de or ch so OBJ rt OPT ho wd cl rm ny mb la av OBJ rt MULT de ho cl rm ny ch mb av OBJ rt SORT 11 OBJ rt UNIQ rt or OBJ rt KEYS rt # NO LONGER USED # # GRDCONFLICT - Text including header to be used in case of guardian # conflicts. To field simply defaults to "guardian". It must be a # local account/alias to mail to. # GRDCONFLICT From: RIPE Database Conflict Handler # GRDCONFLICT Subject: Guarded attributes conflicts found # GRDCONFLICT Cc: marten at ripe.net # GRDCONFLICT # GRDCONFLICT REMEMBER: AS OF OCT 13, ENTRIES IN GUARDIAN FILES MUST # GRDCONFLICT *EXACTLY* MATCH OBJECTS IN THE DATABASE !!!!!!!!!!!!!! # GRDCONFLICT # GRDCONFLICT Dear Guardian, # GRDCONFLICT # GRDCONFLICT One or more conflicts have been found regarding guarded # GRDCONFLICT attributes in the RIPE database. Some of the conflicts # GRDCONFLICT concern the guarded values you are a guardian for. # GRDCONFLICT # GRDCONFLICT Please verify and correct the conflicts below. # GRDCONFLICT The guarded values for objects below have been set to # GRDCONFLICT the value they had in the database before this guarded # GRDCONFLICT attributes run. # GRDCONFLICT # GRDCONFLICT Kind Regards, # GRDCONFLICT RIPE Database Conflict Department # GRDCONFLICT ------ # # NO LONGER USED # # SPLITMSG - Message (including header) to be send when a block of # network numbers has been split due to guarded attribute addition. # The To field is always the email address that last changed the # network block. Some variables to be used here as well: # $BEGINADDRESS - first address of the block that was split # $ENDADDRESS - last address of the block that was split # # SPLITMSG From: RIPE Database Management # SPLITMSG Subject: $BEGINADDRESS - $ENDADDRESS has been split # SPLITMSG Cc: marten at ripe.net, tony at ripe.net # SPLITMSG # SPLITMSG # SPLITMSG Dear last changer of the RIPE database entry # SPLITMSG $BEGINADDRESS - $ENDADDRESS, # SPLITMSG # SPLITMSG This is to notify that network block $BEGINADDRESS - $ENDADDRESS # SPLITMSG has been split due to the addition of guarded attributes. It has # SPLITMSG been split into the objects displayed below in the RIPE database. # SPLITMSG # SPLITMSG Please update your local information accordingly, # SPLITMSG # SPLITMSG RIPE Database Maintenance Department # NO LONGER USED # # legal connect attribute values in alphabetic order # also RIPE database specific used for syntax checking, may move to # different config file later .... # # CONNECT ACONET # CONNECT ALT # CONNECT CIX # CONNECT CNR # CONNECT DATANET # CONNECT EASI # CONNECT EBONE # CONNECT EMPB # CONNECT EU # CONNECT EU-FI # CONNECT FICIX # CONNECT FUNET # CONNECT GARR # CONNECT HEPNET # CONNECT ICS # CONNECT INFN # CONNECT IRIS # CONNECT IUNET # CONNECT JANET # CONNECT LANLINK # CONNECT LOCAL # CONNECT NETTUNO # CONNECT NIKHEF # CONNECT NLNET # CONNECT NORDU # CONNECT NSF # CONNECT PIPEX # CONNECT POWERWAN # CONNECT RCCN # CONNECT REDIRIS # CONNECT RENATER # CONNECT RIPE # CONNECT SARA # CONNECT SURF # CONNECT SWIP # CONNECT SWITCH # CONNECT TIP # CONNECT WCW # CONNECT WIN # CONNECT XLINK ENDCONF # do not remove! -------- Logged at Wed Nov 23 15:16:58 MET 1994 --------- From Marten.Terpstra at ripe.net Wed Nov 23 15:03:22 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Wed, 23 Nov 1994 15:03:22 +0100 Subject: syntax.pl patch Message-ID: <9411231403.AA16597@ncc.ripe.net> Folks, I found a bug in syntax.pl where an illegal regular expression in a maintainer object can crash dbupdate. The patch below solves this. -Marten *** /ncc/dbase/src/syntax.pl Thu Nov 17 14:38:29 1994 --- syntax.pl Wed Nov 23 14:56:06 1994 *************** *** 1,8 **** # # $RCSfile: syntax.pl,v $ ! # $Revision: 0.46 $ # $Author: marten $ ! # $Date: 1994/11/17 13:38:27 $ # # ARGUMENTS: *ASSOC object # RETURNS: INTEGER object_status --- 1,8 ---- # # $RCSfile: syntax.pl,v $ ! # $Revision: 0.47 $ # $Author: marten $ ! # $Date: 1994/11/23 13:56:05 $ # # ARGUMENTS: *ASSOC object # RETURNS: INTEGER object_status *************** *** 512,519 **** } else { return; } ! } ! elsif ($authstr[0] ne "MAIL-FROM") { return $O_ERROR, "syntax error in \"$ATTL{$key}\" $value"; } return; --- 512,530 ---- } else { return; } ! } ! elsif ($authstr[0] eq "MAIL-FROM") { ! local($regex) = $value; ! $regex =~ s/^\s*MAIL\-FROM\s*//; ! eval "/$regex/;"; ! if ($@) { ! return $O_ERROR, "\"$regex\" is not a legal regular expression"; ! } else { ! return; ! } ! } ! ! else { return $O_ERROR, "syntax error in \"$ATTL{$key}\" $value"; } return; -------- Logged at Wed Nov 23 16:06:30 MET 1994 --------- From dsj at merit.edu Wed Nov 23 16:06:24 1994 From: dsj at merit.edu (Dale S. Johnson) Date: Wed, 23 Nov 1994 10:06:24 -0500 Subject: CANET.db Message-ID: <199411231506.KAA01736@merit.edu> Eric, > (Dale: I am still looking forward to beta-test code. I am keeping up > a parallel config system to a 181 based system waiting for your release). Here's what we have: 1) A probably-production-quality "radbserver" which integrates nicely with the new RIPE release. It requires Perl-5. Look in ftp.ra.net:pub/radb/tools . 2) A policy expression evaluation program "peval" in Gnu C++ and Bison (particular recent revisions are required). This binary is required for higher level tools. I believe it works completely, though we are still doing a lot of changes to it. I'd call this an alpha (still got debugs, etc). Cengiz at isi.edu and/or ala at merit.edu can point you to it. 3) A set of "pol2filters" routines in perl. This is a rather nice set of routines which read 181 objects, call peval (above), and output net lists with metrics. The logic is all (?) there for input lists and for route servers. Dale is trying to rework this code a bit for production usage now. (Cengiz also has a "view generator" program which produces special Route Server View objects in preparation for config generation). If you'd like to get going, I'd recommend bringing up the radbserver first, checking it out a bit, and then moving on to peval. And/or: you can run the tools against our server. > We should have RIPE data available for bulk transfer shortly (routes are in, > crcd.canet.ca is queryable, policy not yet complete). We would like to know > how to set up a mnt-by attribute with the RA (you could have told me > already; if so please bear with me and tell me again). If documentation > exists, a pointer is fine. Source is "CANET", mnt-by is "CANET-RC". Try submitting it to auto-dbm at radb.ra.net. We have not switched to the new 181 software release yet, so the security stuff is not yet there, but I think we will accept the data just fine. We'll probably turn on the full 181 release code next week. Don't you want your maintainer object to be in CANET.db rather than RADB.db, though? Actually, the whole business of integrating multiple .db files is pretty much unexplored so far. I think this is to be one of the big topics at the IETF rr-impl meeting. I haven't looked at the 181 .db file structure yet: I've heard it is extremely different from 81 (broken into separate files for different types of objects). Let us know the exact details as soon as your data is available. We'd certainly like to start ftp'ing it each morning, and making it available via our server & tools. I expect Marten is ready to do this, too. --Dale =========================================================================== > From config at enfm.utcc.utoronto.ca Tue Nov 22 19:58:35 1994 > To: nsfnet-admin at merit.edu > From: "CA*NET Routing Coordination" > Subject: Bulk Reconfiguration of CA*net > Cc: rw at mci.net, as3561 at merit.edu, config at CAnet.ca, dsj at merit.edu > > Hi, > > We would appreciate it if you could append to all CA*net routes with 577 > anywhere in the announcement list a trailing low priority (usually 4th and > 5th priority) 3561(218) 3561(11), subject to MCI's ok that these last two > exit points are correct (I know the first is, I tool ). We need this change > to be made for the Friday reconfiguration. If it will not make that > reconfiguration window, please contact Eric Carroll at eric at canet.ca. > > We are setting up for the transition off 690, which we hope to complete by > the end of the month. > > We should have RIPE data available for bulk transfer shortly (routes are in, > crcd.canet.ca is queryable, policy not yet complete). We would like to know > how to set up a mnt-by attribute with the RA (you could have told me > already; if so please bear with me and tell me again). If documentation > exists, a pointer is fine. Source is "CANET", mnt-by is "CANET-RC". > > (Dale: I am still looking forward to beta-test code. I am keeping up > a parallel config system to a 181 based system waiting for your release). > > Thanks, > > Eric Carroll for > CA*NET Routing Coordination > -------- Logged at Wed Nov 23 16:22:00 MET 1994 --------- From rlr at merit.edu Wed Nov 23 16:21:51 1994 From: rlr at merit.edu (Rick Riolo) Date: Wed, 23 Nov 1994 10:21:51 -0500 Subject: CANET.db In-Reply-To: Your message of "Wed, 23 Nov 1994 10:06:24 EST." <199411231506.KAA01736@merit.edu> Message-ID: <199411231521.KAA23326@toad.merit.edu> Just to clarify something Dale said: the radbserver distribution he mentioned is as it stands is running with the old ripe81 database (with all objects in one db file). It does recognize the route object, though. The two things that need to be changed are: - support for split db files (now it needs routes and aut-sys in one file per db) - support for new whois parameters, esp classless thingy choices. (Of course one doesn't need to use radbserver for whois queries.) I plan to make it ripe181 compliant next week, just after getting a ripe181 going here. I don't expect it will take a lot of work or changes. - r -------- > From: "Dale S. Johnson" > To: config at CAnet.ca > CC: rr-impl at merit.edu > Eric, > > > (Dale: I am still looking forward to beta-test code. I am keeping up > > a parallel config system to a 181 based system waiting for your release). > > Here's what we have: > > 1) A probably-production-quality "radbserver" which integrates nicely > with the new RIPE release. It requires Perl-5. Look in > ftp.ra.net:pub/radb/tools . > > 2) A policy expression evaluation program "peval" in Gnu C++ and > Bison (particular recent revisions are required). This binary is > required for higher level tools. I believe it works completely, > though we are still doing a lot of changes to it. I'd call this > an alpha (still got debugs, etc). Cengiz at isi.edu and/or > ala at merit.edu can point you to it. > > 3) A set of "pol2filters" routines in perl. This is a rather nice > set of routines which read 181 objects, call peval (above), and > output net lists with metrics. The logic is all (?) there for > input lists and for route servers. Dale is trying to rework > this code a bit for production usage now. > > (Cengiz also has a "view generator" program which produces special > Route Server View objects in preparation for config generation). > > If you'd like to get going, I'd recommend bringing up the radbserver > first, checking it out a bit, and then moving on to peval. And/or: > you can run the tools against our server. > > > > We should have RIPE data available for bulk transfer shortly (routes are in, > > crcd.canet.ca is queryable, policy not yet complete). We would like to know > > how to set up a mnt-by attribute with the RA (you could have told me > > already; if so please bear with me and tell me again). If documentation > > exists, a pointer is fine. Source is "CANET", mnt-by is "CANET-RC". > > Try submitting it to auto-dbm at radb.ra.net. We have not switched to the > new 181 software release yet, so the security stuff is not yet there, but > I think we will accept the data just fine. We'll probably turn on the > full 181 release code next week. > > Don't you want your maintainer object to be in CANET.db rather than RADB.db, > though? Actually, the whole business of integrating multiple .db files > is pretty much unexplored so far. I think this is to be one of the big > topics at the IETF rr-impl meeting. I haven't looked at the 181 .db file > structure yet: I've heard it is extremely different from 81 (broken into > separate files for different types of objects). > > Let us know the exact details as soon as your data is available. We'd > certainly like to start ftp'ing it each morning, and making it available > via our server & tools. I expect Marten is ready to do this, too. > > --Dale > > > =========================================================================== > > > From config at enfm.utcc.utoronto.ca Tue Nov 22 19:58:35 1994 > > To: nsfnet-admin at merit.edu > > From: "CA*NET Routing Coordination" > > Subject: Bulk Reconfiguration of CA*net > > Cc: rw at mci.net, as3561 at merit.edu, config at CAnet.ca, dsj at merit.edu > > > > Hi, > > > > We would appreciate it if you could append to all CA*net routes with 577 > > anywhere in the announcement list a trailing low priority (usually 4th and > > 5th priority) 3561(218) 3561(11), subject to MCI's ok that these last two > > exit points are correct (I know the first is, I tool ). We need this change > > to be made for the Friday reconfiguration. If it will not make that > > reconfiguration window, please contact Eric Carroll at eric at canet.ca. > > > > We are setting up for the transition off 690, which we hope to complete by > > the end of the month. > > > > We should have RIPE data available for bulk transfer shortly (routes are in, > > crcd.canet.ca is queryable, policy not yet complete). We would like to know > > how to set up a mnt-by attribute with the RA (you could have told me > > already; if so please bear with me and tell me again). If documentation > > exists, a pointer is fine. Source is "CANET", mnt-by is "CANET-RC". > > > > (Dale: I am still looking forward to beta-test code. I am keeping up > > a parallel config system to a 181 based system waiting for your release). > > > > Thanks, > > > > Eric Carroll for > > CA*NET Routing Coordination > > -------- Logged at Wed Nov 23 17:04:12 MET 1994 --------- From dsj at merit.edu Wed Nov 23 17:04:08 1994 From: dsj at merit.edu (Dale S. Johnson) Date: Wed, 23 Nov 1994 11:04:08 -0500 Subject: Promoting the GRR at IETF Message-ID: <199411231604.LAA06994@merit.edu> Hi, If things were a little more stable, we probably ought to do a major promotion of RIPE-181 and the Global Routing Registry at the IETF (probably at a plenary session). Since the GRR isn't really pulled together yet, maybe we still ought to make sure we have at least a progress report in identified working groups to build extra-European awareness and participation. NWG? CIDRD? Others? I do think we someone ought to do a plenary at the Spring IETF. And probably a published paper as well. (Besides a RIPE document on the GRR exchange implementation). Thoughts? --Dale -------- Logged at Thu Nov 24 10:56:40 MET 1994 --------- From Marten.Terpstra at ripe.net Thu Nov 24 10:52:37 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Thu, 24 Nov 1994 10:52:37 +0100 Subject: maintainer fix Message-ID: <9411240952.AA26488@ncc.ripe.net> ! This patch is only for people who use the database software to ! update databases Maintainer verification did not work for non-split databases. Please apply the following patch using: patch -l < "a file where you have put the patch below in" in the src directory of the DB software. It patches maintainer.pl (4 lines I think). Don't forget to do a "make" in the DB home directory after. -Marten *** /ncc/Dbase/src/maintainer.pl Thu Nov 17 14:49:39 1994 --- maintainer.pl Thu Nov 24 10:35:38 1994 *************** *** 2 **** ! # $Revision: 1.3 $ --- 2 ---- ! # $Revision: 1.4 $ *************** *** 4 **** ! # $Date: 1994/10/05 12:35:44 $ --- 4 ---- ! # $Date: 1994/11/24 09:35:37 $ *************** *** 110 **** --- 111 ---- + local($dbfile); *************** *** 117 **** ! if (&dbopen(i, *nothing, 0, "$DBFILE{$source}.mt")) { --- 118,123 ---- ! if ($TYPE{$source} eq "SPLIT") { ! $dbfile = "$DBFILE{$source}.mt"; ! } else { ! $dbfile = $DBFILE{$source}; ! } ! if (&dbopen(i, *nothing, 0, $dbfile)) { -------- Logged at Thu Nov 24 11:22:00 MET 1994 --------- From Daniel.Karrenberg at ripe.net Thu Nov 24 11:21:51 1994 From: Daniel.Karrenberg at ripe.net (Daniel Karrenberg) Date: Thu, 24 Nov 1994 11:21:51 +0100 Subject: RWHOIS Bof (conflicts with GRR Meeting) In-Reply-To: Your message of Mon, 21 Nov 1994 10:17:34 EST. <199411211517.KAA29972@merit.edu> Message-ID: <9411241021.AA27005@ncc.ripe.net> Lets all meet there, decide whether it is useful to stay and meet either afterwards or in parallel. Daniel -------- Logged at Fri Nov 25 22:21:50 MET 1994 --------- From GeertJan.deGroot at ripe.net Fri Nov 25 22:21:42 1994 From: GeertJan.deGroot at ripe.net (Geert Jan de Groot) Date: Fri, 25 Nov 1994 22:21:42 +0100 Subject: RR's, PGP and licenses Message-ID: <9411252121.AA11952@ncc.ripe.net> Scanning though the PGP docs, I found this snippet from the RSAREF license: > b. The Program and all Application Programs are to be used only > for non-commercial purposes. However, media costs associated > with the distribution of the Program or Application Programs > may be recovered. Assuming that a RR is commercial (we're all payed to do this, right?), has someone already investigated this with RSA? Geert Jan -------- Logged at Mon Nov 28 16:26:20 MET 1994 --------- From epg at merit.edu Mon Nov 28 16:26:06 1994 From: epg at merit.edu (epg at merit.edu) Date: Mon, 28 Nov 1994 10:26:06 -0500 (EST) Subject: RR's, PGP and licenses In-Reply-To: <9411252121.AA11952@ncc.ripe.net> from "Geert Jan de Groot" at Nov 25, 94 10:21:42 pm Message-ID: <9411281526.AA01434@pepper.merit.edu> Geert Jan, My definition of commercial may be different than yours. Neither the RIPE NCC nor Merit is profiting from the inclusion of PGP in the registry software. We are not selling the software and the organizations which are using the software are just recovering their operating costs - not making profits that are then paid out to stockholders or somebody. But no, we have not investigated this further - it seems like a non- problem. --Elise >Geert Jan de Groot writes: > > > Scanning though the PGP docs, I found this snippet from the RSAREF > license: > > > b. The Program and all Application Programs are to be used only > > for non-commercial purposes. However, media costs associated > > with the distribution of the Program or Application Programs > > may be recovered. > > Assuming that a RR is commercial (we're all payed to do this, right?), > has someone already investigated this with RSA? > > Geert Jan > > > -------- Logged at Mon Nov 28 17:25:27 MET 1994 --------- From Marten.Terpstra at ripe.net Mon Nov 28 17:25:16 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Mon, 28 Nov 1994 17:25:16 +0100 Subject: RR's, PGP and licenses In-Reply-To: Your message of Mon, 28 Nov 1994 10:26:06 EST. <9411281526.AA01434@pepper.merit.edu> Message-ID: <9411281625.AA01118@ncc.ripe.net> * Geert Jan, * * My definition of commercial may be different than yours. Neither the * RIPE NCC nor Merit is profiting from the inclusion of PGP in the * registry software. We are not selling the software and the organizations * which are using the software are just recovering their operating costs - * not making profits that are then paid out to stockholders or * somebody. For the RIPE NCC I think you are right. For MERIT I don't know, you probably know better than we do. However, MERIT, Inc. does not sound like a non-profit organisation ;-) Besides that, I am not sure whether service providers that make use of the software are non-commercial companies... I am sure they are all doing this to make money, right? Not that I really want to get into this discussion, but it is something to think about. * But no, we have not investigated this further - it seems like a non- * problem. It is better to investigate rather than find out afterwards that RSA does think this is a commercial purpose.... -Marten -------- Logged at Mon Nov 28 17:45:04 MET 1994 --------- From dsj at merit.edu Mon Nov 28 17:44:58 1994 From: dsj at merit.edu (Dale S. Johnson) Date: Mon, 28 Nov 1994 11:44:58 -0500 Subject: RR's, PGP and licenses Message-ID: <199411281644.LAA23997@merit.edu> Marten, > * Geert Jan, > * > * My definition of commercial may be different than yours. Neither the > * RIPE NCC nor Merit is profiting from the inclusion of PGP in the > * registry software. We are not selling the software and the organizations > * which are using the software are just recovering their operating costs - > * not making profits that are then paid out to stockholders or > * somebody. > > For the RIPE NCC I think you are right. For MERIT I don't know, you > probably know better than we do. However, MERIT, Inc. does not > sound like a non-profit organisation ;-) Merit is a tax-exempt non-profit educational organization, officially certified by the US Internal Revenue Service. That's as official as you can get for non-profit in this country. Moreover, the project this code is used for is directly funded by the US National Science Foundation; that alone would probably qualify the project. > Besides that, I am not sure > whether service providers that make use of the software are > non-commercial companies... I am sure they are all doing this to make > money, right? Not that I really want to get into this discussion, but > it is something to think about. I could easily imagine that the server side of the code is covered, but that the client sides at MCI or SprintNet or ANS COO+RE would not be covered. Good point. We might have to bundle the client source in such a way that a for-profit firm can load it with a fee-paid version of RSA. (And, presumably, be ready to supply information about how and where they can officially pay the fee). > > * But no, we have not investigated this further - it seems like a non- > * problem. > > It is better to investigate rather than find out afterwards that RSA > does think this is a commercial purpose.... sigh. True. > > -Marten > --Dale -------- Logged at Mon Nov 28 18:53:59 MET 1994 --------- From epg at merit.edu Mon Nov 28 18:53:47 1994 From: epg at merit.edu (epg at merit.edu) Date: Mon, 28 Nov 1994 12:53:47 -0500 (EST) Subject: RR's, PGP and licenses In-Reply-To: <199411281644.LAA23997@merit.edu> from "Dale S. Johnson" at Nov 28, 94 11:44:58 am Message-ID: <9411281753.AA01517@pepper.merit.edu> We will investigate. Thanks. --Elise -------- Logged at Mon Nov 28 19:47:27 MET 1994 --------- From bmanning at ISI.EDU Mon Nov 28 19:47:17 1994 From: bmanning at ISI.EDU (Bill Manning) Date: Mon, 28 Nov 1994 10:47:17 -0800 (PST) Subject: Promoting the GRR at IETF Message-ID: <199411281847.AA20197@zephyr.isi.edu> Hi Dale, 1- Can you add me to this mailing list? 2- The Gated people have asked for a rundown on the RS and the GRR. 3- I received two additional requests, one from some IEPG folks and one from the NAP folks for run-downs on the RS and GRR status and some high-level implementation details. That would be for the Saturday and Sunday before IETF (gated & iepg) and then on tuesday. --bill -------- Logged at Tue Nov 29 15:31:44 MET 1994 --------- From Marten.Terpstra at ripe.net Tue Nov 29 15:22:07 1994 From: Marten.Terpstra at ripe.net (Marten Terpstra) Date: Tue, 29 Nov 1994 15:22:07 +0100 Subject: more bug fixes ... Message-ID: <9411291422.AA11077@ncc.ripe.net> Bug in inet-rtr interface address indexing this time. -Marten PS Patch in the "src" directory of the db software: patch -l < "the file name with the patch below in it" *** /ncc/Dbase/src/cldb.pl Thu Nov 24 22:14:48 1994 --- cldb.pl Tue Nov 29 15:18:20 1994 *************** *** 1,5 **** # $RCSfile: cldb.pl,v $ ! # $Revision: 1.6 $ # $Author: marten $ ! # $Date: 1994/11/17 13:43:57 $ --- 1,5 ---- # $RCSfile: cldb.pl,v $ ! # $Revision: 1.7 $ # $Author: marten $ ! # $Date: 1994/11/29 14:18:19 $ *************** *** 170,171 **** --- 170,172 ---- $len = 16; + $len = 32 if $4; $one_net = 0x00010000; *************** *** 173,174 **** --- 174,176 ---- $len = 8; + $len = 32 if $4; $one_net = 0x01000000; -------- Logged at Wed Nov 30 19:08:43 MET 1994 --------- From cengiz at ISI.EDU Wed Nov 30 19:07:45 1994 From: cengiz at ISI.EDU (Cengiz Alaettinoglu) Date: Wed, 30 Nov 1994 10:07:45 -0800 Subject: syntax errors moving isitest.db to ripe181 In-Reply-To: <199411292143.QAA12234@_radb.ra.net> References: <199411292143.QAA12234@_radb.ra.net> Message-ID: <199411301807.AA15119@chl.isi.edu> Rick Riolo (rlr at _radb.ra.net) on November 29: > hi cengiz, > in moving isitest.db onto _radb.ra.net, under ripe181, > I am getting some errors with an objects in isitest.db . > could you please take a look at the errors and the objects > and let me know what you think...is it ripe or our problem? Most of the cases, error messages were right. (Actually I am impressed with the detail of the error messages. Is it possible to list those error messages right after the offending line?) There are two cases in which I think error messages were erronous:-) I think {0/0} is a valid network-list. I think NSF_DB{ aslist == * } is a valid db selector. I am including examples below. Cengiz Alaettinoglu (cengiz at _radb.ra.net) on November 30: > Update FAILED: [aut-num] AS1239 > > aut-num: AS1239 > descr: SprintNet > as-in: from AS690 1 accept ANY AND NOT {0/0} > as-in: from AS3561 1 accept ANY AND NOT {0/0} > as-out: to AS690 announce ANY > as-out: to AS3561 announce ANY > guardian: dsj at merit.edu > admin-c: Jack Waters > tech-c: Jack Waters > mnt-by: MAINT-ISI > changed: dsj at merit.edu 941007 > source: ISITEST > *ERROR*: syntax error in "as-in: peer AS690 cost 1" > *ERROR*: netlist error {0/0} > *ERROR*: syntax error in "as-in: peer AS3561 cost 1" > *ERROR*: netlist error {0/0} > > Update FAILED: [aut-num] AS690 > > aut-num: AS690 > descr: NSFNET/ANSNet > as-in: from AS1239 1 accept NSF_DB{ aslist == * } > as-in: from AS3561 1 accept NSF_DB{ aslist == * } > as-out: to AS3561 announce NSF_DB{ aslist == * } > interas-in: from AS3561 198.32.132.10/32 198.32.132.12/32 (pref = 1) accept AS-MCIEAST > interas-in: from AS3561 198.32.132.10/32 198.32.132.12/32 (pref = 2) accept AS-MCIMIDWEST > interas-in: from AS3561 198.32.132.10/32 198.32.132.12/32 (pref = 3) accept AS-MCIWEST > interas-in: from AS3561 198.32.130.10/32 198.32.130.12/32 (pref = 1) accept AS-MCIMIDWEST > interas-in: from AS3561 198.32.130.10/32 198.32.130.12/32 (pref = 2) accept AS-MCIEAST > interas-in: from AS3561 198.32.130.10/32 198.32.130.12/32 (pref = 3) accept AS-MCIWEST > interas-in: from AS3561 198.32.128.10/32 198.32.128.12/32 (pref = 1) accept AS-MCIWEST > interas-in: from AS3561 198.32.128.10/32 198.32.128.12/32 (pref = 2) accept AS-MCIMIDWEST > interas-in: from AS3561 198.32.128.10/32 198.32.128.12/32 (pref = 3) accept AS-MCIEAST > admin-c: Elise Gerich > tech-c: Steve Widmayer > mnt-by: MAINT-ISI > changed: dsj at merit.edu 941007 > source: ISITEST > *ERROR*: syntax error in "as-in: peer AS1239 cost 1" > *ERROR*: netlist error { ASlist == * } > *ERROR*: syntax error in "as-in: peer AS3561 cost 1" > *ERROR*: netlist error { ASlist == * } > *ERROR*: syntax error in "as-out: peer AS3561 " > *ERROR*: netlist error { ASlist == * } Cengiz -- Cengiz Alaettinoglu Information Sciences Institute cengiz at isi.edu University of Southern California -------- Logged at Wed Nov 30 19:12:41 MET 1994 --------- From Tony.Bates at ripe.net Wed Nov 30 19:12:20 1994 From: Tony.Bates at ripe.net (Tony Bates) Date: Wed, 30 Nov 1994 19:12:20 +0100 Subject: syntax errors moving isitest.db to ripe181 In-Reply-To: Your message of Wed, 30 Nov 1994 10:07:45 PST. <199411301807.AA15119@chl.isi.edu> Message-ID: <9411301812.AA28528@ncc.ripe.net> cengiz at ISI.EDU (Cengiz Alaettinoglu) writes: * * Rick Riolo (rlr at _radb.ra.net) on November 29: * > hi cengiz, * > in moving isitest.db onto _radb.ra.net, under ripe181, * > I am getting some errors with an objects in isitest.db . * > could you please take a look at the errors and the objects * > and let me know what you think...is it ripe or our problem? * * Most of the cases, error messages were right. * Thanks ;-). * (Actually I am impressed with the detail of the error messages. Is it * possible to list those error messages right after the offending line?) * * There are two cases in which I think error messages were erronous:-) * I think {0/0} is a valid network-list. No sorry it isn't - check the definiton. * I think NSF_DB{ aslist == * } is a valid db selector. There is no code for DB selecter in the original code. This needs to be added if you want to work. I assumed Merit would do tihs if they want to make use of it. --tony. * I am including examples below. * * Cengiz Alaettinoglu (cengiz at _radb.ra.net) on November 30: * > Update FAILED: [aut-num] AS1239 * > * > aut-num: AS1239 * > descr: SprintNet * > as-in: from AS690 1 accept ANY AND NOT {0/0} * > as-in: from AS3561 1 accept ANY AND NOT {0/0} * > as-out: to AS690 announce ANY * > as-out: to AS3561 announce ANY * > guardian: dsj at merit.edu * > admin-c: Jack Waters * > tech-c: Jack Waters * > mnt-by: MAINT-ISI * > changed: dsj at merit.edu 941007 * > source: ISITEST * > *ERROR*: syntax error in "as-in: peer AS690 cost 1" * > *ERROR*: netlist error {0/0} * > *ERROR*: syntax error in "as-in: peer AS3561 cost 1" * > *ERROR*: netlist error {0/0} * > * > Update FAILED: [aut-num] AS690 * > * > aut-num: AS690 * > descr: NSFNET/ANSNet * > as-in: from AS1239 1 accept NSF_DB{ aslist == * } * > as-in: from AS3561 1 accept NSF_DB{ aslist == * } * > as-out: to AS3561 announce NSF_DB{ aslist == * } * > interas-in: from AS3561 198.32.132.10/32 198.32.132.12/32 (pref = 1) acc * ept AS-MCIEAST * > interas-in: from AS3561 198.32.132.10/32 198.32.132.12/32 (pref = 2) acc * ept AS-MCIMIDWEST * > interas-in: from AS3561 198.32.132.10/32 198.32.132.12/32 (pref = 3) acc * ept AS-MCIWEST * > interas-in: from AS3561 198.32.130.10/32 198.32.130.12/32 (pref = 1) acc * ept AS-MCIMIDWEST * > interas-in: from AS3561 198.32.130.10/32 198.32.130.12/32 (pref = 2) acc * ept AS-MCIEAST * > interas-in: from AS3561 198.32.130.10/32 198.32.130.12/32 (pref = 3) acc * ept AS-MCIWEST * > interas-in: from AS3561 198.32.128.10/32 198.32.128.12/32 (pref = 1) acc * ept AS-MCIWEST * > interas-in: from AS3561 198.32.128.10/32 198.32.128.12/32 (pref = 2) acc * ept AS-MCIMIDWEST * > interas-in: from AS3561 198.32.128.10/32 198.32.128.12/32 (pref = 3) acc * ept AS-MCIEAST * > admin-c: Elise Gerich * > tech-c: Steve Widmayer * > mnt-by: MAINT-ISI * > changed: dsj at merit.edu 941007 * > source: ISITEST * > *ERROR*: syntax error in "as-in: peer AS1239 cost 1" * > *ERROR*: netlist error { ASlist == * } * > *ERROR*: syntax error in "as-in: peer AS3561 cost 1" * > *ERROR*: netlist error { ASlist == * } * > *ERROR*: syntax error in "as-out: peer AS3561 " * > *ERROR*: netlist error { ASlist == * } * * * * Cengiz * * -- * Cengiz Alaettinoglu Information Sciences Institute * cengiz at isi.edu University of Southern California * -------- Logged at Wed Nov 30 19:49:55 MET 1994 --------- From cengiz at ISI.EDU Wed Nov 30 19:49:05 1994 From: cengiz at ISI.EDU (Cengiz Alaettinoglu) Date: Wed, 30 Nov 1994 10:49:05 -0800 Subject: syntax errors moving isitest.db to ripe181 In-Reply-To: <9411301812.AA28528@ncc.ripe.net> References: <199411301807.AA15119@chl.isi.edu> <9411301812.AA28528@ncc.ripe.net> Message-ID: <199411301849.AA15161@chl.isi.edu> Tony Bates (Tony.Bates at ripe.net) on November 30: > > cengiz at ISI.EDU (Cengiz Alaettinoglu) writes: > * > * Rick Riolo (rlr at _radb.ra.net) on November 29: > * > hi cengiz, > * > in moving isitest.db onto _radb.ra.net, under ripe181, > * > I am getting some errors with an objects in isitest.db . > * > could you please take a look at the errors and the objects > * > and let me know what you think...is it ripe or our problem? > * > * Most of the cases, error messages were right. > * > Thanks ;-). > > * (Actually I am impressed with the detail of the error messages. Is it > * possible to list those error messages right after the offending line?) > * > * There are two cases in which I think error messages were erronous:-) > * I think {0/0} is a valid network-list. > > No sorry it isn't - check the definiton. A Route List is a list of routes in prefix length format, separated by commas, and surrounded by curly brackets (braces, i.e. `{' and '}'). Unfortunately prefix length format is not defined in Ripe-181 but in Ripe-121. 3.1. Prefix Length This representation is a dotted quad followed by a slash and the de- cimal length in bits of the prefix. Well, I could not find a definition for "dotted quad":-) Rick, please replace {0/0} with {0.0.0.0/0}. Cengiz -- Cengiz Alaettinoglu Information Sciences Institute cengiz at isi.edu University of Southern California -------- Logged at Mon Dec 5 20:27:59 MET 1994 ---------