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

📄 iprouter.java

📁 一个小型网络仿真器的实现
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
    voport.spq_size+= (frame.length()>>3);

    if(voport.spq.size()==1) { //must schedule a processing slot if spq previously empty
      long ticks=SimClock.USec2Tick(frame.length() / (double)sw_speed.getValue());
      theSim.enqueue(new SimEvent(MY_SLOT_TIME,this,this,theSim.now()+ticks,voport));
    }
  }

  protected void sw_receive(SimEvent e) {
    SimComponent src=(SimComponent)e.getSource();

    if(src.getCompClass().equals("Link")) {
      EtherFrame frame=(EtherFrame)e.getParams();
      long ticks;
  
      ticks=SimClock.USec2Tick(sw_delay.getValue() * (frame.length()>>3));
      theSim.enqueue(new SimEvent(MY_RECEIVE,src,this,
                          theSim.now()+ticks,e.getParams()));
  
      //update frames count
      sw_frames_received.setValue(sw_frames_received.getValue()+1,theSim.now(),sw_log_factor.getValue());

      //inform the analyzer
      if(analyzer!=null) analyzer.update(frame,src,this);
    }
    else { //no processing delay if from apps
      theSim.enqueue(new SimEvent(MY_RECEIVE,src,this,
                          theSim.now(),e.getParams()));
    }
  }

  protected void drop_frame_clas() {
    sw_dropped_clas.setValue(sw_dropped_clas.getValue()+1,theSim.now(),sw_log_factor.getValue());
  }

  protected void sw_my_receive(SimEvent e) {
    SimComponent src=(SimComponent)e.getSource();
    Port voport=null;;

    if(src.getCompClass().equals("Link")) {
      voport=(Port)voports.get(src);
      if(voport==null) return; //should not be...

      EtherFrame frame=(EtherFrame)e.getParams();
      if(frame.dest_mac!=voport.mac_addr &&
          (frame.dest_mac & 0x333300000000L)!=0x333300000000L &&
          frame.dest_mac!=0xffffffffffffL)
        return; //throw it away if wrong target

      switch(frame.type) {
        case EtherFrame.ETHER_IP:
          sw_receive_IP((IPPacket)frame.payload,voport);
          return;
        case EtherFrame.ETHER_ARP:
          sw_receive_ARP((ARPPacket)frame.payload,voport);
          return;
        default:
          drop_frame_clas();
          return; //unsupported type, just throw it away
      }
    }
    else { //IP Packet from apps
      //we shall fill in the source IP for this packet
      IPPacket packet=(IPPacket)e.getParams();
      packet.sourceIP=getMyIP();

      //then send for processing as usual
      sw_receive_IP(packet,null);
    }
  }

  //helper, return smallest ip, or localhost ip if no interface ip
  protected int getMyIP() {
    long ip=0xffffffffL;
    java.util.Iterator i=voports.values().iterator();
    while(i.hasNext()) {
      Port voport=(Port)i.next();
      long portip=((long)voport.ip.getValue())&0xffffffffL;
      if(portip!=0 && portip<ip) {
        ip=portip;
      }
    }
    if(ip!=0xffffffffL) return (int)ip;
    else return 0x7f000001;
  }

  protected void sw_receive_IP_for_me(IPPacket packet,Port fromport) {
    AppInfo app;
    switch(packet.protocol) {
      case IPPacket.PRO_TCP:
        TCPSegment seg=(TCPSegment)packet.payload;
        app=(AppInfo)apps.get(new Integer((packet.protocol<<16)|seg.destport));
        if(app==null || app.comp==this)
          sw_tcp.receive_ip(packet,fromport.to_link); //handle it here
        else if(app.comp instanceof SimComponent) {
          theSim.enqueue(new SimEvent(SimProvider.EV_RECEIVE,this,(SimComponent)app.comp,
                                      theSim.now(),packet));
        }
        else { //then it must be an IPProtocol
          ((IPProtocol)app.comp).receive_ip(packet,(fromport==null)?null:fromport.to_link);
        }
        break;
      case IPPacket.PRO_UDP:
        UDPPacket udp=(UDPPacket)packet.payload;
        app=(AppInfo)apps.get(new Integer((packet.protocol<<16)|udp.destport));
        if(app==null) return; //no valid receiver found, just sink it

        if(app.comp instanceof SimComponent) {
          theSim.enqueue(new SimEvent(SimProvider.EV_RECEIVE,this,(SimComponent)app.comp,
                                      theSim.now(),packet));
        }
        else { //then it must be an IPProtocol
          ((IPProtocol)app.comp).receive_ip(packet,(fromport==null)?null:fromport.to_link);
        }
        break;
      default:
        break;
    }
  }

  protected void sw_send_IP(IPPacket packet,SimComponent tolink) {
    //get port
    Port voport=(Port)voports.get(tolink);
    if(voport==null) { //shouldn't be!
      System.out.println("WARNING: sw_receive_IP: target link has no Port!");
      return;
    }

    //check multicast
    if((packet.destIP & 0xf0000000)==0xe0000000) {
      send_etherframe(packet,0,voport,
              0x333300000000L | ((long)packet.destIP & 0xfffffffL));
    }
    else
      send_etherframe(packet,0,voport,0);
  }

  protected void sw_receive_IP(IPPacket packet,Port fromport) {
  //check local destination
    java.util.Iterator i=voports.values().iterator();
    while(i.hasNext()) {
      Port voport=(Port)i.next();

      if(packet.destIP==voport.ip.getValue()) {
        sw_receive_IP_for_me(packet,fromport);
        return;
      }
    }
    //support local loopback
    if(packet.destIP==0x7f000001) {
      sw_receive_IP_for_me(packet,fromport);
      return;
    }

    //check multicast
    if((packet.destIP & 0xf0000000)==0xe0000000) {
      if(fromport==null) { //outgoing
        //go out all ports
        i=voports.values().iterator();
        while(i.hasNext()) {
          Port voport=(Port)i.next();
          send_etherframe(packet,0,voport,
                  0x333300000000L | ((long)packet.destIP & 0xfffffffL));
        }
      }
      else { //incoming
        sw_receive_IP_for_me(packet,fromport);
      }
      return;
    }

  //foreign destination, lookup forwarding table
    IPRouteEntry route=sw_route_table.lookup(packet.destIP);
    if(route==null) { //not found, drop it
      drop_frame_clas();
      return;
    }

    //else forward it
    Port voport=(Port)voports.get(route.nexthop);
    if(voport==null) return; //cannot be!

    send_etherframe(packet,route.nexthopIP,voport,0);
  }

  //helper for sending Ethernet frame
  //(check multicast first, if 0, then check nexthopIP, if 0, then direct)
  protected void send_etherframe(IPPacket packet,int nexthopIP,Port voport,
                                long multicast) {
    EtherFrame frame=new EtherFrame();
    if(multicast==0) {
      if(nexthopIP==0) frame.dest_mac=mac_lookup(packet.destIP,voport);
      else frame.dest_mac=mac_lookup(nexthopIP,voport);
      if(frame.dest_mac==0xffffffffffffffffL) { //not found
        if(sw_arp_q.getValue()==true) {
          //fill in nexthop info (in dest mac field) and queue the packet
          frame.dest_mac=(nexthopIP==0)?packet.destIP:nexthopIP;
          frame.src_mac=voport.mac_addr;
          frame.len=packet.len;
          frame.type=EtherFrame.ETHER_IP;
          frame.payload=packet;
          voport.arp_q.add(frame);
        }
        else {
          drop_frame_clas();
        }
        return;
      }
    }
    else
      frame.dest_mac=multicast;

    frame.src_mac=voport.mac_addr;
    frame.len=packet.len;
    frame.type=EtherFrame.ETHER_IP;
    frame.payload=packet;
    sw_send_spq(frame,voport);
  }

  protected long mac_lookup(int ip,Port voport) {
    ARPEntry entry=(ARPEntry)voport.arp_entries.get(new Integer(ip));
    if(entry==null) { //not found, trigger a request
      ARPPacket arp=new ARPPacket();
      arp.opcode=ARPPacket.ARP_REQUEST;
      arp.dest_mac=0;
      arp.dest_IP=ip;
      arp.src_mac=voport.mac_addr;
      arp.src_IP=voport.ip.getValue();

      EtherFrame frame=new EtherFrame();
      frame.dest_mac=0xffffffffffffL;
      frame.src_mac=voport.mac_addr;
      frame.len=46;
      frame.type=EtherFrame.ETHER_ARP;
      frame.payload=arp;
      sw_send_spq(frame,voport);

      return 0xffffffffffffffffL;
    }
    return entry.mac;
  }

  protected void sw_receive_ARP(ARPPacket arp,Port voport) {
    //update arp entries if possible
    ARPEntry entry=(ARPEntry)voport.arp_entries.get(new Integer(arp.src_IP));
    if(entry==null) { //new, add it
      entry=new ARPEntry();
      entry.IP=arp.src_IP;
      entry.mac=arp.src_mac;
      voport.arp_entries.put(new Integer(entry.IP),entry);

      //check the arp_q
      if(!voport.arp_q.isEmpty()) {
        java.util.Iterator i=voport.arp_q.iterator();
        while(i.hasNext()) {
          EtherFrame frame=(EtherFrame)i.next();
          if(entry.IP==(int)frame.dest_mac) { //found
            frame.dest_mac=entry.mac;
            i.remove();
            sw_send_spq(frame,voport);
          }
        }
      }
    }

    if(arp.opcode==ARPPacket.ARP_REQUEST) {
      if(arp.dest_IP==voport.ip.getValue()) { //OK, generate reply
        arp.opcode=ARPPacket.ARP_REPLY;
        arp.dest_mac=arp.src_mac;
        arp.dest_IP=arp.src_IP;
        arp.src_mac=voport.mac_addr;
        arp.src_IP=voport.ip.getValue();

        EtherFrame frame=new EtherFrame();
        frame.dest_mac=arp.dest_mac;
        frame.src_mac=voport.mac_addr;
        frame.len=46;
        frame.type=EtherFrame.ETHER_ARP;
        frame.payload=arp;
        sw_send_spq(frame,voport);
      }
    }
    //NOTE: for REPLY packet, we already got it from the update code above :)
  }


////////////////////// SimCommand services ///////////////////////

  protected transient SimGUI theGUI=null;
  protected transient int oldselcount=0;

  public SimCommand querySimCommand(int selectedCount) {
    oldselcount=selectedCount;
    return this;
  }

  public void analyzerUp(Analyzer a) {
    analyzer=a;
  }
  public void analyzerDown(Analyzer a) {
    analyzer=null;
  }

  public java.util.List getCommand(Sim aSim,SimGUI aGUI) {
    java.util.List cmd=new java.util.ArrayList();

    JMenuItem menuItem=new JMenuItem("Clear Route Table");
    menuItem.addActionListener(this);
    cmd.add(menuItem);

    if(oldselcount==1) { //allow analyzer if only one is selected
      if(analyzer!=null) cmd.addAll(analyzer.getCommand(aSim,aGUI));
      else cmd.addAll((new Analyzer(this,this)).getCommand(aSim,aGUI));
    }

    theGUI=aGUI;

    return cmd;
  }

  public void actionPerformed(ActionEvent e) {
    if(e.getActionCommand().equals("Clear Route Table")) {
      java.util.List selcomps=theGUI.getSelected();
      int i;
      for(i=0;i<selcomps.size();i++) {
        SimComponent thiscomp=(SimComponent)selcomps.get(i);
        if(thiscomp instanceof IPRouter) {
          IPRouter r=(IPRouter)thiscomp;
          r.sw_route_table.clearTable();
        }
      }
    }
  }
}

⌨️ 快捷键说明

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