#!/usr/bin/ruby # vim: et sw=2 VER="(985514d)" ME="route.rb: " $incl=[] $excl=[] $skip=[] $rtrs=[] class String def is_tp(tp) tp.each_byte do |a| f=true self.each_byte do |b| if a==b f=false break end end return false if f end return true end end def in_list(s,list) for i in list if i.match(s) return true end end return false end def regexfix(str) tmp=[] for t in str.scan(/(_)|(\|)|([^_\|]*)/).flatten.compact tmp.push(t) if not t.empty? end res="" while t=tmp.shift case t when("_") then res+=(tmp.empty? or tmp[0]=="|") ? "([ .]+|$)" : "[ .]+" when("|") then res+="|" else res+="#{t}" end end return res end class Node attr_reader :nm, :ip attr_accessor :idx def initialize(nm,ip,tp) @nm=nm @ip=ip @tp=tp end def label if is_tp("N") return "[#{@ip}]" if @nm==@ip return "#{@nm} [#{@ip}]" end return "#{@nm}" end def is_tp(tp) tp.each_byte do |a| f=true @tp.each_byte do |b| if a==b f=false break end end return false if f end return true end def add_tp(tp) tp.each_byte do |a| f=true @tp.each_byte do |b| if a==b f=false break end end @tp.concat(a) if f end end def del_tp(tp) @tp.delete!(tp) end def color return ["#c9fbc9","#c9fbc9"] if is_tp("A") return ["#ceaece","#ceaece"] if is_tp("L") return ["#a359e6","#a359e6"] if is_tp("C") return ["#59dbe1","#59dbe1"] if is_tp("U") return ["#48e248","#48e248"] if is_tp("N") return ["#ef715a","#ef715a"] if is_tp("r") return ["#ffffff","#ffffff"] end end def get_gw(ip) ai=ip.split(".") bf=ip.split("/")[1].to_i return nil if ai.length!=4 i=0 while bf>7 i+=1 bf-=8 end bf=8-bf bf=255<7 i=ai.shift.to_i m=am.shift.to_i return false if i!=m bf-=8 end return true if bf==0 i=ai.shift.to_i m=am.shift.to_i bf=8-bf bf=255<7 net.concat(".") if not net.empty? net.concat(ai.shift()) bf=bf-8 c-=1 end return net+"/"+tmp[1] if c<1 i=ai.shift().to_i bf=8-bf bf=255<0 net.concat(".0") c-=1 end return net+"/"+tmp[1] end def is_node_rt?(s) return case s when(/^rt-/i) then true when(/^swr-/i) then true when(/^sw3-/i) then true when(/^C17/i) then true when(/^C28/i) then true when(/^C3[567]/i) then true when(/^C45/i) then true when(/^C6[58]/i) then true when(/^C7[236]/i) then true when(/^Quanta-/i) then true when(/^Wbx-/i) then true else false end end def load_file(buf,fn) dir=File.dirname(fn) begin f=File.open(fn,"r") rescue $stderr.puts ME+"unable to open file" exit end for l in f l.chop! next if l.empty? next if /^! /.match(l) buf.push(l) end f.close end def usage me=ME.delete(":") puts "Usage: "+me+"[-I ] [-X ] [-S ] ..." exit end i=0 while i=ARGV.length for l in $stdin l.chop! next if l.empty? next if /^! /.match(l) next if /^<[^>]*>$/.match(l) buf.push(l) end else while i]*>$/.match(l) buf.push(l) end else load_file(buf,fn) end end end Link=Struct.new :n1, :n2 $nodes={} $links=[] def $nodes.get_node(ip) self.each_value do |n| return n if n.ip==ip end return nil end def $links.get_link(n1,n2) for l in self return l if l.n1==n1 and l.n2==n2 return l if l.n1==n2 and l.n2==n1 end return nil end inbl=igbl=false hdr=fld=nil bl=gn=bn=nil for s in buf if inbl if /^--+/.match(s) inbl=igbl=false hdr=fld=nil bl=gn=bn=nil next end next if igbl next if !bl a=s.split(/\t+/) next if a[0].empty? ip=a[0] next if ip.include?("-") if a[1] nm=a[1].split(":")[0] else nm=ip.delete(" ") end if !/^ /.match(ip) next if nm.start_with?("-") or nm.start_with?("?") or nm.start_with?("(") next if not $incl.empty? and not in_list(nm,$incl) next if in_list(nm,$excl) if !gn gw=get_gw(bl.ip) if gw==ip if !gn=$nodes[nm] gn=Node.new(nm,ip,"r") $nodes[nm]=gn else gn.add_tp("r") end bn=gn next end end end if m=/^ ([0-9.]+\/[0-9]+)/.match(ip) next if !bn bn.add_tp("r") next end if not ip.include?("/") ip.delete!(" ") if !bn=$nodes[nm] bn=Node.new(nm,ip,"") $nodes[nm]=bn end bn.add_tp("r") if bl.is_tp("R") next end next end if /^#!/.match(s) igbl=true next end if /^#/.match(s) hdr=s next end if /^--+/.match(s) inbl=true if in_list(hdr,$skip) igbl=true next end if m=/^# +\(([^ ]*)\)|^# +([^()]*) +\(([^ ]*)\)/.match(hdr) if m[1] nm=m[1] ip=m[1] else nm=m[2] ip=m[3] end tp=nil if m=/\{(.*)\}/.match(hdr) tp=m[1] end if tp and tp.is_tp("A") igbl=true next end if tp and tp.is_tp("X") igbl=true next end bl=Node.new(nm,ip,"N") $nodes[nm]=bl bl.add_tp(tp) if tp bl.add_tp("R") if in_list(hdr,$rtrs) else igbl=true end next end fld=s if hdr end $nodes.delete_if do |k,v| next false if v.is_tp("N") next false if v.is_tp("r") next true end inbl=igbl=false hdr=fld=nil n1=n2=bn=nil for s in buf if inbl if /^--+/.match(s) inbl=igbl=false hdr=fld=nil n1=n2=bn=nil next end next if igbl next if !n1 a=s.split(/\t+/) next if a[0].empty? ip=a[0] next if ip.include?("-") if a[1] nm=a[1].split(":")[0] else nm=ip.delete(" ") end if m=/^ ([0-9.]+\/[0-9]+)/.match(ip) next if !bn ip=m[1] if !n2=$nodes.get_node(ip) n2=Node.new(ip,ip,"N") $nodes[ip]=n2 end next if $links.get_link(bn,n2) $links<
EOF f.close fork { exec("start /tmp/route.htm") }