📄 iphandler.java
字号:
// No entry, create a new one, start timeout that will invalidate
// this fragment list after a while
if(frag_entry == null)
{
frag_entry = new Fragment(curpacket.id);
m_fragments.addElement(frag_entry);
// Schedule a timeout that will delete this id's fragments if
// they aren't complete yet by then
class FragmentTimeoutCommand extends Command
{
int m_id;
FragmentTimeoutCommand(int id, double time)
{
super("FragmentTimeout", time);
m_id = id;
}
public void execute()
{
// Look through fragments, they might not exist anymore
// because they are complete..
for(int i = 0; i < m_fragments.size(); i++)
{
Fragment curfragment = (Fragment) m_fragments.elementAt(i);
if(curfragment.getId() == m_id)
{
m_fragments.removeElementAt(i);
return;
}
}
}
}
Simulator.getInstance().schedule(new FragmentTimeoutCommand(
curpacket.id, Simulator.getInstance().getTime() +
Preferences.ip_fragmentation_timeout));
}
// Add this packet to the list of fragments
frag_entry.addFragment(curpacket);
// If we are complete, reassemble
if(frag_entry.complete())
{
Simulator.verbose("Packet complete!!");
IPPacket packet = frag_entry.reassemble();
// Remove from fragment list
for(int i = 0; i < m_fragments.size(); i++)
{
Fragment curfragment = (Fragment) m_fragments.elementAt(i);
if(curfragment.getId() == packet.id)
{
m_fragments.removeElementAt(i);
return;
}
}
// Pass on to higher level protocol
HigherAgent destagent = (HigherAgent)
m_protocols.get(new Integer(curpacket.protocol));
if(destagent != null)
{
destagent.queue.pushFront(curpacket);
destagent.agent.indicate(Agent.PACKET_AVAILABLE, this);
}
else
{
// TODO: No destination protocol.. Generate a custom event ?
}
}
}
}
}
}
/**
* Private function that processes a packet to be sent to a certain destination
*/
/**
Send an IP packet. This queues the packet into the send queue and
schedules a call to update().
*/
public void send(IPAddr source, IPAddr dest, int length, Object data,
int unique_id)
{
IPPacket packet = new IPPacket();
packet.source = new IPAddr(source);
packet.destination = new IPAddr(dest);
packet.length = IPPacket.HEADER_SIZE + length;
packet.data = data;
packet.id = m_packetid++;
packet.protocol = unique_id;
// Put packet in the send queue
m_packets_send.pushFront(packet);
// Schedule a call to the update function
Simulator.getInstance().schedule(new ElementUpdateCommand(this,
Simulator.getInstance().getTime() +
Preferences.delay_ip_to_ifacequeue));
}
public Object read(int unique_id)
{
HigherAgent destagent = (HigherAgent)
m_protocols.get(new Integer(unique_id));
if(destagent == null)
{
Simulator.warning("Higher level agent with unknown id called read()");
return null;
}
IPPacket packet = (IPPacket) destagent.queue.peekBack();
destagent.queue.popBack();
return packet;
}
public boolean canSend(IPAddr destination, int length)
{
Interface target = m_route.getRoute(destination);
return target.canSend(destination, length);
}
/**
Indicate to this IP handler that a packet is waiting for collection
@param status the status that is indicated, as defined in Agent
@param indicator the object that is giving is the packet, must be an
Interface object.
@see Agent
*/
public void indicate(int status, Object indicator)
{
if(!(indicator instanceof Interface))
Simulator.error("IPHandler received an indication from a non-Interface");
if((status & Agent.READY_TO_SEND) != 0)
{
Simulator.verbose("IPHandler got READY_TO_SEND");
// Schedule a call to the update function
Simulator.getInstance().schedule(new ElementUpdateCommand(this,
Simulator.getInstance().getTime() +
Preferences.delay_ifacequeue_to_ip));
// Notify all agents above us that we're ready to send.
for(Enumeration e = m_protocols.elements(); e.hasMoreElements();)
{
HigherAgent curagent = (HigherAgent) e.nextElement();
curagent.agent.indicate(Agent.READY_TO_SEND, this);
}
}
else if((status & Agent.PACKET_AVAILABLE) != 0)
{
IPPacket packet = (IPPacket) ((Interface) indicator).read(0);
// Stick the packet in the receive queue
m_packets_recv.pushFront(packet);
// Schedule a call to the update function
Simulator.getInstance().schedule(new ElementUpdateCommand(this,
Simulator.getInstance().getTime() +
Preferences.delay_ifacequeue_to_ip));
}
else
Simulator.warning("IPHandler received an unhandled indication: " + status);
}
public void addRoute(IPAddr dest, IPAddr netmask, Interface iface)
{
m_route.addRoute(dest, netmask, iface);
}
public void addDefaultRoute(Interface iface)
{
m_route.addDefaultRoute(iface);
}
public RoutingTable getRoutingTable()
{
return m_route;
}
public Enumeration enumerateInterfaces()
{
return m_interfaces.elements();
}
}
class HigherAgent
{
public jns.util.Queue queue;
public Agent agent;
public HigherAgent(Agent agent)
{
this.agent = agent;
queue = new jns.util.Queue();
}
}
/**
Auxiliary class to represent the fragments of one IP packet. Contains the
ID of the packet and a number of fragment packets.
*/
class Fragment
{
private int m_id;
private Vector m_packets;
public Fragment(int id)
{
m_id = id;
m_packets = new Vector();
}
public int getId()
{
return m_id;
}
public boolean complete()
{
int offset = 0;
for(int i = 0; i < m_packets.size(); i++)
{
IPPacket curpacket = (IPPacket) m_packets.elementAt(i);
// Offsets don't match, there a packet missing, fail
if(curpacket.fragment_offset != offset) return false;
// Last packet, but 'more fragments' set, so fail
if(i == m_packets.size() - 1)
if((curpacket.flags & IPPacket.FLAG_MORE_FRAGMENTS) != 0)
return false;
offset = offset + (curpacket.length >> 3);
}
return true;
}
public void addFragment(IPPacket packet)
{
int i = 0;
Simulator.verbose(m_packets.size());
Simulator.verbose(packet.fragment_offset);
if(m_packets.size() == 0)
{
m_packets.addElement(packet);
return;
}
while(i < m_packets.size() &&
(((IPPacket) m_packets.elementAt(i)).fragment_offset <
packet.fragment_offset))
i++;
// Ignore duplicates
if(i < m_packets.size() &&
((IPPacket) m_packets.elementAt(i)).fragment_offset ==
packet.fragment_offset)
return;
m_packets.insertElementAt(packet, i);
}
/**
Reassemble a broken up IP packet. This is easy because the data does
not actually ever get split up.. :)
*/
public IPPacket reassemble()
{
int length = 0;
// Simply copy the first IP packet because it contains almost all of the
// original packt
IPPacket packet = new IPPacket((IPPacket) m_packets.elementAt(0));
// Reset the flags and length
packet.length = 0;
packet.flags = 0;
// Rebuild the original length field
Enumeration e = m_packets.elements();
while(e.hasMoreElements())
{
IPPacket curpacket = (IPPacket) e.nextElement();
packet.length += curpacket.length;
}
return packet;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -