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

📄 iphandler.java

📁 The Java Network Simulator is a Java implementation of the ns-2 simulator originally from Berkeley.n
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/**
 TODO LIST FOR IPHANDLER

 - Process time to live field
 - look at copy_options field in ip packets
 -
 */

package jns.element;

import jns.Simulator;
import jns.agent.Agent;
import jns.agent.CL_Agent;
import jns.command.Command;
import jns.command.ElementUpdateCommand;
import jns.util.IPAddr;
import jns.util.Preferences;
import jns.util.RoutingTable;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;


public class IPHandler extends Element implements CL_Agent
{

    private Vector m_interfaces;

    private jns.util.Queue m_packets_send;  // Packets waiting to be sent
    private jns.util.Queue m_packets_recv;  // Received packets to be processed

    private Vector m_fragments;   // A vector of Fragment objects (See below)

    private RoutingTable m_route;

    private int m_packetid;         // Unique packet id

    private Hashtable m_protocols;  // Higher level protocols, stores instances
    // of 'HigherAgent'


    public IPHandler()
    {
        m_interfaces = new Vector();

        m_packets_send = new jns.util.Queue();
        m_packets_recv = new jns.util.Queue();

        m_route = new RoutingTable();

        // Get a new unique packet id start from the current time in millisecs
        // and a random number between 0-10000.

        //m_packetid=(int)((new Date()).getTime())+(int)(Math.random()*10000.0);
        m_packetid = 0;

        m_fragments = new Vector();


        m_protocols = new Hashtable();
    }


    public void attach(Interface iface)
    {

        // If the appropriate flag is set, make this iface the default route

        if(Preferences.first_iface_is_default_route && m_interfaces.isEmpty())
        {
            m_route.addDefaultRoute(iface);
        }

        // Make this handler that interfaces handler

        iface.setIPHandler(this);

        // Add to interface list

        m_interfaces.addElement(iface);
    }


    public void attach(Agent higher_level, int unique_id)
    {

        // Create a new receive queue, etc. for this agent

        HigherAgent newagent = new HigherAgent(higher_level);
        m_protocols.put(new Integer(unique_id), newagent);

        // Reverse attach ourselves to this agent (allow it to make a reference)

        higher_level.attach(this);
    }

    public void attach(Agent lower_level)
    {
        Simulator.error("You may not attach a lower level agent to an IP " +
                        "handler (because there is no such thing!)");
    }


    public void dump()
    {
        System.out.println("IP Handler");

        Enumeration e = m_interfaces.elements();
        while(e.hasMoreElements())
            ((Element) e.nextElement()).dump();
    }


    public IPAddr getAddress()
    {
        if(m_interfaces.size() > 0)
        {
            Interface iface = (Interface) m_interfaces.firstElement();
            return iface.getIPAddr();
        }
        else
            return null;
    }


    /**
     The update function will process the send queue and the receive queue
     of the IPHandler. Everything in the send queue will be given to an
     interface to send, if possible. Things in the receive queue will be
     forwarded to a higher level protocol or if this is a router, sent on
     to the next hop.
     */
    public void update()
    {
        Simulator.verbose("Updating IP Handler");

        // Process packets waiting to be sent

        while(m_packets_send.size() > 0)
        {

            // Remove a packet from the queue

            IPPacket curpacket = (IPPacket) m_packets_send.peekBack();
            m_packets_send.popBack();


            Vector targets = new Vector();

            if(curpacket.destination.isMulticastAddress())
            {

                //Get all the targets, as a multicast packet should be sent to all the
                //neigbouring nodes..
                targets = m_route.getAllRoutes();
                //deliver the packet to myself, as that is the required behaviour of
                //multicast
                m_packets_recv.pushBack(new IPPacket(curpacket));
            }
            else
            {
                targets.add(m_route.getRoute(curpacket.destination));
            }

            boolean canSend = true;
            for(int j = 0; j < targets.size(); j++)
            {
                //check that we canSend() on all the interfaces..
                 if(!((Interface)targets.get(j)).canSend(curpacket.destination, curpacket.length))
                    {
                        m_packets_send.pushFront(curpacket);
                        canSend = false;
                        Simulator.verbose("The interface on which to send to: "+curpacket.destination+" is busy, pushing packet onto msg queue again.");
                        break;
                    }
            }


            if(canSend)
            {
                for(int j = 0; j < targets.size(); j++)
                {

                    if(targets.size() == 0)
                        Simulator.warning("No route to address " +
                                          curpacket.destination + " from " +
                                          curpacket.source);
                    else
                    {

                       // Check if we have to fragment...

                        if(((Interface)targets.get(j)).getMTU() >= curpacket.length)
                        {
                            //Copy the packet, to use if we send more than one..
                            IPPacket sendPacket = new IPPacket(curpacket);
                            ((Interface)targets.get(j)).send(sendPacket);
                        }
                        else
                        {
                            // Maximum packet length (must be a multiple of 8 with IP)
                            int maximum_length = ((Interface)targets.get(j)).getMTU() & (~7);

                            // Number of fragments to generate
                            int num_packets = (curpacket.length / maximum_length) + 1;
                            int offset = 0;

                            Simulator.verbose("Fragmenting big packet into " + num_packets +
                                              " fragments.");

                            for(int i = 0; i < num_packets; i++)
                            {
                                // Copy the original packet
                                IPPacket new_fragment = new IPPacket(curpacket);

                                // Last fragment

                                if(i == (num_packets - 1))
                                {
                                    // Note that we do not handle the more_fragments bit here. If
                                    // we are refragmenting a fragmented packet, it's set already
                                    // otherwise it's unset, which is fine.. last packet..

                                    new_fragment.length = curpacket.length % maximum_length;
                                }
                                else
                                {
                                    new_fragment.flags |= IPPacket.FLAG_MORE_FRAGMENTS;
                                    new_fragment.length = maximum_length;
                                }

                                new_fragment.fragment_offset = (offset >> 3);
                                offset += new_fragment.length;

                                // Off it goes..
                                ((Interface)targets.get(j)).send(new_fragment);
                            }
                        }
                    }
                }
            }
        }

        // Received packets waiting to be sent on or given to higher level
        // protocols

        while(m_packets_recv.size() > 0)
        {
            IPPacket curpacket = (IPPacket) m_packets_recv.peekBack();
            m_packets_recv.popBack();

            // Check the packet's integrity

            if(!curpacket.crc)
            {
                // TODO: Generate drop packet event ?

                // Get next packet instead
                continue;
            }

            // Check if the packet's destination IP address equals on of our
            // interfaces addresses..

            boolean is_final_dest = false;

            Enumeration e = m_interfaces.elements();
            while(e.hasMoreElements())
            {
                Interface curiface = (Interface) e.nextElement();

                if(curiface.getIPAddr().equals(curpacket.destination))
                {
                    Simulator.verbose("Packet at final dest");
                    is_final_dest = true;
                    break;
                }
            }

            // If this is not a final destination, send it on
            //TODO: IMPORTANT: I'm pretty sure that the last conditional on this if statement
            // breaks the standard, fixed line IP handling of multicast addresses, but it's
            //the desired behaviour for 802.11b in ad hoc mode!
            if(!is_final_dest && !curpacket.destination.isMulticastAddress())
            {
                Simulator.verbose("Sending on packet");

                m_packets_send.pushFront(curpacket);

                Simulator.getInstance().schedule(new ElementUpdateCommand(this,
                                                                          Simulator.getInstance().getTime() +
                                                                          Preferences.delay_ip_to_ifacequeue));
            }
            else
            {
                // Not a fragment because offset=0 and no 'more fragments' flags set

                if(curpacket.fragment_offset == 0 &&
                        (curpacket.flags & IPPacket.FLAG_MORE_FRAGMENTS) == 0)
                {

                    // 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 ?
                    }
                }
                else
                {

                    // There's a fragment lurking around, perform reassembly.

                    Fragment frag_entry = null;

                    // Find if there is an entry in the fragment list

                    e = m_fragments.elements();
                    while(e.hasMoreElements())
                    {
                        Fragment curfragment = (Fragment) e.nextElement();

                        if(curfragment.getId() == curpacket.id)
                        {
                            frag_entry = curfragment;
                            break;
                        }
                    }

⌨️ 快捷键说明

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