⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rip.java

📁 一个小型网络仿真器的实现
💻 JAVA
字号:
/*
   JaNetSim  ---  Java Network Simulator
   -------------------------------------

   This software was developed at the Network Research Lab, Faculty of
   Computer Science and Information Technology (FCSIT), University of Malaya.
   This software may be used and distributed freely. FCSIT assumes no responsibility
   whatsoever for its use by other parties, and makes no guarantees, expressed or
   implied, about its quality, reliability, or any other characteristic.

   We would appreciate acknowledgement if the software is used.

   FCSIT ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
   DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
   FROM THE USE OF THIS SOFTWARE.
*/

package janetsim.component;

import janetsim.*;
import java.io.Serializable;

/**
 * RIP version 2.0 
 * IMPORTANT: This is a stub version
 */
public class RIP implements UDPUser, UDPProvider, IPProtocol, SimListener, Serializable {
 
  /* Communication attributes */
  private UDP udp;
  private Object udp_key;
  private IPRouter owner;
  
  /* RIP constants */
  /** RIP Port number, Port 520 */
  public static final int RIP_PORT = 520; 
  /** AF_INET number */
  public static final int AF_INET = 2;
  /** Maximum number of RIP entries in a RIP message */
  public static final int RIP_ENTRY_MAX = 25;
  /** RIP version used here */
  public static final int RIP_VERSION = 2;  
  /** Type of entry in IProuter for RIP */
  public static final String ROUTE_TYPE = "RIPv2";
  
  /* Timer values */
  /** Route time out in seconds */
  public static final int TIME_OUT = 180;
  /** Route garbage collection time in seconds */
  public static final int GARBAGE_COLLECTION = 60;
  
  /* RIP components */
  /** Routing table within RIP */
  private RouteTable RIProuteTable;
      
  /**
   * Required simulation component constructor     
   */
  public RIP (IPRouter owner) {
    this.owner = owner;
    udp = new UDP(owner, this);
    
    /* register RIP port */
    Object [] parms = new Object[3];
    parms[0] = new Integer(RIP_PORT);
    parms[1] = new Integer(IPPacket.PRO_UDP);
    parms[2] = this;
    if(owner.compInfo(IPRouter.GET_PRV_PORT,null,parms)==null) {
      System.out.println("Warning: RIP PORT occupied!");
    }
    RIProuteTable = new RouteTable();
  }

/* IP protocol methods */
 /**
  * Reset RIP
  */
  public void reset() {
    udp.reset();  
    RIProuteTable.clear(); 
    //System.out.println("RIP Reset");     
  }
  
 /**
  * Start RIP
  */
  public void start() {
    int srcip = ((Integer)owner.compInfo(IPRouter.GET_IP,null,null)).intValue();
    udp_key=udp.open(srcip,RIP_PORT,0,0,this);    
    System.out.println("RIP Started");
  }

 /**
  * Method to process IP packets received
  */
  public void receive_ip(IPPacket packet, SimComponent fromLink) {
    udp.receive_ip(packet, fromLink);     
  }    

/* UDPProvider methods */
 /**
  * The RIP processing delay
  * Currently there is no delay
  */
  public double getDelay() {
    return 0;
  }
  
 /**
  * The RIP processing delay variation
  * Currently there is no delay variation
  */
  public double getDelayVar() {
    return 0;
  }
  
 /**
  * Method to handle the sending of IP packets
  */
  public void sendPacket(IPPacket packet) {
    owner.compInfo(SimProvider.CI_TRANSPORT_SEND,null,packet);          
  }

 /**
  * Method to handle the targeted sending of IP packets
  */
  public void sendPacket(IPPacket packet,SimComponent tolink) {
    Object [] parms=new Object[2];
    parms[0]=packet;
    parms[1]=tolink;
    owner.compInfo(SimProvider.CI_TRANSPORT_SEND2LINK,null,parms);          
  }

 /**
  * Method to handle changes in the connection status
  */
  public void statusChanged() {
  }

/* UDPUser methods */
 /**
  * Method to recieve packets 
  * This method processes incoming RIP messages
  */
  public void receive_packet(int src_ip,int src_port, SimComponent fromLink, UDPBuffer buf) {
    //add incoming processing here...
  }     

/**
 * Action method for listener
 */  
  public void action (SimEvent e) {
    //add incoming event handling here...      
  }        
}

/** 
 * RIP Message 
 * The RIP Messages that are used
 */
class RIPMsg implements Serializable {

  /* Command types */
  /** Request command */
  public static final int REQUEST = 1;
  /** Response command */
  public static final int RESPONSE = 2;      
        
  /* header attributes */
  /** Command attribute */
  public int command; 
  /** Version */
  public int version;    
  
  /* RIP entry */
  /** RIP entries */
  public java.util.Vector entries;
  
  /* Derived RIP values */
  /** Number of entries */
  public int numberEntries;
  /** Size fo RIP message in bytes */
  public int size;
  
 /**
  * RIP message constructor
  */
  public RIPMsg (int commandIn) {
    command = commandIn;
    version = RIP.RIP_VERSION;
    entries = new java.util.Vector();
    numberEntries = 0;  
    size = 4;     
  }
 
 /**
  * Adds a RIP entry into the RIP message by specifying parameters
  * Will not add the RIP entry if the number of entries is already at maximum
  */
  public void addEntry (int addressFamilyIn, int IPAddressIn, int subnetMaskIn, int nextHopIn, int metricIn, int routeTagIn) {
    RIPEntry tempRIPEntry = new RIPEntry(addressFamilyIn, IPAddressIn, subnetMaskIn, nextHopIn, metricIn, routeTagIn);
    addEntry(tempRIPEntry);
  }
  
 /**
  * Adds a RIP entry into the RIP message
  * Will not add the RIP entry if the number of entries is already at maximum
  */
  public void addEntry (RIPEntry entryIn) {
    if (canAddEntry()) {
      entries.add(entryIn);
      numberEntries++;   
      size = size + 20;
    }
  }
  
 /**
  * Checks if more entries can be added to this RIP message
  * Returns true if more entries can be added, false if otherwise
  */ 
  public boolean canAddEntry () {
    if (numberEntries >= RIP.RIP_ENTRY_MAX)
      return false;
    else
      return true;       
  }  
}

/**
 * RIP Entry information
 * Contains route information
 */
class RIPEntry implements Serializable {
  /* header attributes */
  /** Address family identifier - only AF_INET supported, zero if General Request Message */
  public int addressFamily;
  /** IP addresses */
  public int IPAddress;     
  /** Subnet mask*/   
  public int subnetMask;
  /** Next hop address */
  public int nextHop;
  /** Metric value */
  public int metric;
  /** Route tag */
  public int routeTag;
  
 /**
  * RIP entry constructor
  */
  public RIPEntry (int addressFamilyIn, int IPAddressIn, int subnetMaskIn, int nextHopIn, int metricIn, int routeTagIn) {
    addressFamily = addressFamilyIn;
    IPAddress = IPAddressIn;
    subnetMask = subnetMaskIn;
    nextHop = nextHopIn;
    metric = metricIn;
    routeTag = routeTagIn;      
  } 
}

/**
 * Route Table
 * Contains the entire route table for RIP
 */
class RouteTable implements Serializable {
  /** The route table as a list of Route Entries */ 
  private java.util.Vector rtable;
 
 /**
  * Route table constructor
  */
  public RouteTable () {
    rtable = new java.util.Vector();       
  }       
  
 /**
  * Lookup a route entry
  * Lookup searches in order from the most general mask to the most specific mask
  * Returns a route entry, returns null if no match found
  */
  public RouteEntry lookup (int IP) {
    //performs longest match lookup
    RouteEntry tempRouteEntry;
    for (java.util.Enumeration myEnumeration = rtable.elements(); myEnumeration.hasMoreElements(); ) {
      tempRouteEntry = (RouteEntry) myEnumeration.nextElement();
      if ((IP & tempRouteEntry.mask) == tempRouteEntry.ip) return tempRouteEntry;         
    }
    return null;
  } 
  
 /**
  * Locates a route entry
  * Route entries are located by their ip address and masks
  * Returns the route entry found, or null if no entry is found that matches
  */
  public RouteEntry getEntry (int IPin, int maskIn) {
    RouteEntry tempRouteEntry;
    for (java.util.Enumeration myEnumeration = rtable.elements(); myEnumeration.hasMoreElements(); ) {
      tempRouteEntry = (RouteEntry) myEnumeration.nextElement();
      if ((IPin == tempRouteEntry.ip) && (maskIn == tempRouteEntry.mask)) return tempRouteEntry;      
    }
    return null;
  }
  
 /**
  * Adds a route entry by accepting route parameters 
  * Note that insertion is done without prior checks
  */
  public void add (int IPin, int maskIn, int nextHopIn, SimComponent compIn, Timer timeoutTimerIn, Timer garbageCollectionTimerIn) {
    RouteEntry re = new RouteEntry(IPin, maskIn, nextHopIn, compIn, timeoutTimerIn, garbageCollectionTimerIn);
    add (re);
  }
  
 /**
  * Adds a route entry by accepting a Route Entry
  * Note that insertion is done without prior checks
  */
  public void add (RouteEntry entryIn) {
    //binary search to find insertion point
    int left = 0;
    int right = rtable.size() - 1;   
    int insertPoint = 0;
    while (left <= right) {
      int middle = (left + right) / 2;
      if (entryIn.mask == ( (RouteEntry)rtable.get(middle) ).mask ) {
        do {
          middle++;
          if ( middle == rtable.size() ) break;
        } while ( entryIn.mask == ( (RouteEntry)rtable.get(middle) ).mask );
        insertPoint = middle;
        break;
      }
      if (isLongerMask(((RouteEntry)rtable.get(middle)).mask, entryIn.mask)) {
        left = middle + 1;
        insertPoint = left;
      }
      else {
        insertPoint = middle;
        right = middle - 1;
      }
    }
    rtable.add(insertPoint, entryIn);
  }
  
 /**
  * Private method to determine if first mask is longer than second mask 
  */
  private boolean isLongerMask (int mask1, int mask2) {
    if (mask1 == 0) return false;         
    return (mask1 > mask2 || (mask1 != 0 && mask2 == 0));
  }
  
 /**
  * Removes a route from the route table
  * Does nothing if the entry is not found in the route table
  */
  public void remove (int IP, int mask) {
    RouteEntry tempEntry = getEntry(IP, mask);
    if (tempEntry != null) {
      rtable.remove(tempEntry);      
    }
  }
  
 /**
  * Clears entire route table
  */
  public void clear() {
    rtable.clear();       
  }
}

/**
 * Route Entry
 * A single route entry in the Route Table
 */ 
class RouteEntry implements Serializable {
 /** IP Address of destination network/host - 32 bits */
 public int ip;
 /** Mask of destination network/host - 32 bits */
 public int mask;
 /** IP address of the next hop - 32 bits, use 0 for direct connection*/
 public int nextHopIp;
 /** The simcomponent representing the next hop */
 public SimComponent nextHop;
 /** Route change flag - true if changed, false otherwise */
 public boolean routeChanged;   
 /** Route timeout timer */
 public Timer timeoutTimer;
 /** Route garbage collection timer */
 public Timer garbageCollectionTimer;

 /**
  * Route Entry constructor
  */
  public RouteEntry (int ipIn, int maskIn, int nextHopIpIn, SimComponent nextHopIn, Timer timeoutTimerIn, Timer garbageCollectionTimerIn) {
    ip = ipIn;
    mask = maskIn;
    nextHopIp = nextHopIpIn;
    nextHop = nextHopIn;
    routeChanged = false;       
    timeoutTimer = timeoutTimerIn;
    garbageCollectionTimer = garbageCollectionTimerIn;
  }
}

/** 
 * Timer object
 * Used to maintain timer information and allow setting, starting, stopping and resetting of timers
 */
class Timer implements Serializable {
  /** Reference to the component using this timer */
  private SimComponent comp;
  /** The listener using this timer */      
  private SimListener listener;
  /** The Event currently being timed by this timer */
  private SimEvent event = null;
  /** The type of Event currently being timed by this timer */
  private int eventType;
  /** The length of time (in seconds) that this timer will be active for */
  private double timerDuration;
  /** The paramaters for the event queue representing this timer */
  private Object params; 
  
 /**
  * Timer constructor 
  */
  public Timer (SimComponent compIn, SimListener listenerIn, int eventTypeIn, double timerDurationIn, Object paramsIn) {
    comp = compIn;
    listener = listenerIn;
    eventType = eventTypeIn;
    timerDuration = timerDurationIn;
    params = paramsIn;         
  }
  
 /**
  * Set the timer's duration
  */
  public void setTimerDuration (double timerDurationIn) {
    timerDuration = timerDurationIn;       
  }
 
 /**
  * Start the timer
  * Will restart the timer if the timer is already started
  */
  public void start () {
    if (event != null) { //stop the old timer that is running
      comp.getSim().dequeue(event);
      event = null;       
    }        
    event = new SimEvent(eventType, listener, listener, comp.getSim().now() + SimClock.Sec2Tick(timerDuration), params);
    comp.getSim().enqueue(event);
  }    
  
 /**
  * Stop the timer
  * Also call this method when the timer event is received
  */
  public void stop () {
    if (event != null) { //stop the old timer that is running
      comp.getSim().dequeue(event);
    }
    event = null;                
  }
  
 /**
  * Determines if the timer is currently running
  */
  public boolean isRunning () {
    return ( event != null );       
  }
}

        
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -