📄 iprouter.java
字号:
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 + -