module Scriptroute::Tulip::LangChecker

whether a given IP speaks a particular language ##########

Public Class Methods

getBestOption(destination, *prefList) click to toggle source
# File lib/scriptroute/tulip/helper.rb, line 7
def LangChecker.getBestOption(destination, *prefList)
  prefList.each { |type| 
    case type
    when "tstamp"
      return "tstamp" if(LangChecker.probeResponse(destination, 
                                                   Scriptroute::ICMP::ICMP_TSTAMP, 
                                                   Scriptroute::ICMP::ICMP_TSTAMPREPLY)) 
    when "echo"
      return "echo" if(LangChecker.probeResponse(destination, 
                                                 Scriptroute::ICMP::ICMP_ECHO, 
                                                 Scriptroute::ICMP::ICMP_ECHOREPLY))
    when "udp"
      return "udp" if(LangChecker.udp(destination))
    when "tcp" 
      return "tcp" if(LangChecker.tcp(destination))
    else
      raise("ERROR: unknown packet type = #{type}");
    end
  }
  return nil;
end
getBestOption4IPIDs(destination, *prefList) click to toggle source
# File lib/scriptroute/tulip/helper.rb, line 29
def LangChecker.getBestOption4IPIDs(destination, *prefList)
  prefList.each { |type| 
    return [type, true] if(LangChecker.increasingIPIDs(destination, 255, type));
  }   
  return [nil, false];
end
getBestPathOption4IPIDs(destination, ttl, router, tpath) click to toggle source
# File lib/scriptroute/tulip/helper.rb, line 163
def LangChecker.getBestPathOption4IPIDs(destination, ttl, router, tpath)
  canCheckForward = (LangChecker.increasingIPIDs(destination, ttl, "udp"))? 1 : -1;
  #puts "ccf = #{canCheckForward}\n";
  if (canCheckForward == -1) then
    ##todo: can be extended to other types, such as timestamps
    if (LangChecker.increasingIPIDs(router, 255, "echo")) then  
      subpath = TracePath.new(router);
      puts "subpathto #{router}:\n#{subpath.to_s}\n";
      if (tpath.subset(subpath)) then
        return [router, 255, "echo", 1];       
      end
    end
  end
  ## the default
  return [destination, ttl, "udp", canCheckForward];
end
getDefaultPacket(type, seq=0) click to toggle source
# File lib/scriptroute/tulip/helper.rb, line 142
def LangChecker.getDefaultPacket(type, seq=0) 
  if (type == "udp") 
    return Scriptroute::UDP.new(12);
  elsif (type == "tcp") 
    probe = Scriptroute::TCP.new(0);
    probe.th_dport=80;
    probe.th_win=1024;
    return probe;
  else 
    probe = if (type == "echo")
              Scriptroute::ICMPecho.new(0)
            elsif (type == "tstamp")
              Scriptroute::ICMPtstamp.new(0)
            else 
              raise "ERROR: unsupported packettype #{type} in sendAndReceiveTrain\n";
            end
    probe.icmp_seq=seq;
    return probe;
  end
end
increasingIPIDs(destination, ttl, type) click to toggle source
# File lib/scriptroute/tulip/helper.rb, line 82
  def LangChecker.increasingIPIDs(destination, ttl, type)     
    #puts "lchecker: increasing ip-ids #{destination} #{ttl} #{type}";
    delayedArray = Array.new();
    (0..2).each { |i|
      probe = LangChecker.getDefaultPacket(type, i);
      probe.ip_dst = destination;
      probe.ip_ttl = ttl;
      delayedArray.push(Struct::DelayedPacket.new(0.001, probe));
    }
    begin
      packets = Scriptroute::send_train(delayedArray);
    rescue Exception => e
      $stderr.puts "Exception #{e} sending:"
      delayedArray.each_with_index { |dp,i| $stderr.puts "%d: %s" % [ i, dp.packet.to_s ] }
      return false
    end
    
    if (!packets[0] || !packets[1] || !packets[2] || 
                     !packets[0].response || !packets[1].response || !packets[2].response)
      return false;
    end
    
#      puts "%s (ttl=%d, %s): %s %s %s  --> %d %d %d" % [destination, ttl, type,
#        packets[0].response.packet.ip_src,
#        packets[1].response.packet.ip_src,
#        packets[2].response.packet.ip_src,
#        packets[0].response.packet.ip_id,
#        packets[1].response.packet.ip_id,
#        packets[2].response.packet.ip_id];

#     puts "%.3f %.3f %.3f" % [packets[0].probe.time.to_f*1000,
#      packets[1].probe.time.to_f*1000,
#      packets[2].probe.time.to_f*1000];


    ##zeroes are being returned
    return false if (packets[0].response.packet.ip_id == 0 && packets[1].response.packet.ip_id == 0);
    
    ##the remote destination is copying my id's
    return false if (packets[0].response.packet.ip_id == packets[0].probe.packet.ip_id &&
                     packets[1].response.packet.ip_id == packets[1].probe.packet.ip_id);
    
    #puts "passed zero and copy test\n";

    #    packets.sort! { |a,b| a.probe.time <=> b.probe.time };
    ids = packets.map { |p| p.response.packet.ip_id };
    
    return true if (AliasResolution.before(ids[0]-10, ids[1]) && 
                    AliasResolution.before(ids[1], ids[0]+200) && 
                    ids[0] != ids[1] &&
                    AliasResolution.before(ids[1]-10, ids[2]) && 
                    AliasResolution.before(ids[2], ids[1]+200) && 
                    ids[1] != ids[2]);

    #puts "failed maternity test with #{ids.join(" ")}\n";

    return false;

  end
probeResponse(destination, probeType, responseType) click to toggle source
# File lib/scriptroute/tulip/helper.rb, line 37
def LangChecker.probeResponse(destination, probeType, responseType)
  probe = Scriptroute::ICMP.new(0);
  probe.ip_dst = destination;
  probe.icmp_type = probeType;
  probe.icmp_code = 0;
  probe.icmp_seq = 0;
  packets = Scriptroute::send_train([Struct::DelayedPacket.new(0, probe)]);
  return false if (!packets[0].response);
  response = packets[0].response.packet;
  if (response.is_a?(Scriptroute::ICMP) && 
      response.icmp_type == responseType) 
    return true;
  end
  return false;
end
tcp(destination) click to toggle source
# File lib/scriptroute/tulip/helper.rb, line 72
def LangChecker.tcp(destination)
  probe = Scriptroute::TCP.new(12) 
  probe.ip_dst = destination;
  packets = Scriptroute::send_train([Struct::DelayedPacket.new(0, probe)]);
  return false if (!packets[0].response);
  response = packets[0].response.packet;
  puts response
  return (response.is_a?(Scriptroute::TCP) && response.flag_rst)
end
udp(destination) click to toggle source
# File lib/scriptroute/tulip/helper.rb, line 53
def LangChecker.udp(destination)
  probe = Scriptroute::UDP.new(12) 
  probe.ip_dst = destination;
  begin 
    packets = Scriptroute::send_train([Struct::DelayedPacket.new(0, probe)]);
  rescue Exception => e
    puts "sluffing exception" + e
    return false
  end
  return false if (!packets[0].response);
  response = packets[0].response.packet;
  if (response.is_a?(Scriptroute::ICMP) &&
      response.icmp_type == Scriptroute::ICMP::ICMP_UNREACH &&
      response.icmp_code == Scriptroute::ICMP::ICMP_UNREACH_PORT )
    return true;
  end
  return false;
end