Encapsulates an EthernetPacket and provides the mechanisms to generate new Ethernet Packets. This is immutable.
The Header is of the format: Field Position Destination Address6 bytes Source Address6 bytes Type2 bytes DataThe rest
Inheritance: NetworkPacket
示例#1
0
文件: IpopNode.cs 项目: xujyan/ipop
        ///<summary>This sends an ICMP Request to the specified address, we want
        ///him to respond to us, so we can guarantee that by pretending to be the
        ///Server (i.e. x.y.z.1).  We'll get a response in our main thread.</summary>
        ///<param name="dest_ip">Destination IP of our request.</summary>
        protected virtual void SendICMPRequest(MemBlock dest_ip)
        {
            if(_dhcp_server == null) {
            return;
              }
              MemBlock ether_addr = null;
              if(!_ip_to_ether.TryGetValue(dest_ip, out ether_addr)) {
            ether_addr = EthernetPacket.BroadcastAddress;
              }

              ICMPPacket icmp = new ICMPPacket(ICMPPacket.Types.EchoRequest);
              IPPacket ip = new IPPacket(IPPacket.Protocols.ICMP, _dhcp_server.ServerIP,
              dest_ip, icmp.Packet);
              EthernetPacket ether = new EthernetPacket(ether_addr,
              EthernetPacket.UnicastAddress, EthernetPacket.Types.IP, ip.ICPacket);
              Ethernet.Send(ether.ICPacket);
        }
示例#2
0
文件: IpopNode.cs 项目: xujyan/ipop
        /// <summary>Writes an IPPacket as is to the TAP device.</summary>
        /// <param name="packet">The IPPacket!</param>
        protected virtual void WriteIP(ICopyable packet)
        {
            MemBlock mp = packet as MemBlock;
              if(mp == null) {
            mp = MemBlock.Copy(packet);
              }

              IPPacket ipp = new IPPacket(mp);
              MemBlock dest = null;
              if(!_ip_to_ether.TryGetValue(ipp.DestinationIP, out dest)) {
            return;
              }

              EthernetPacket res_ep = new EthernetPacket(_ip_to_ether[ipp.DestinationIP],
              EthernetPacket.UnicastAddress, EthernetPacket.Types.IP, mp);
              Ethernet.Send(res_ep.ICPacket);
        }
示例#3
0
文件: IpopNode.cs 项目: xujyan/ipop
        /// <summary>This is used to process a dhcp packet on the node side, that
        /// includes placing data such as the local Brunet Address, Ipop Namespace,
        /// and other optional parameters in our request to the dhcp server.  When
        /// receiving the results, if it is successful, the results are written to
        /// the TAP device.</summary>
        /// <param name="ipp"> The IPPacket that contains the DHCP Request</param>
        /// <param name="dhcp_params"> an object containing any extra parameters for 
        /// the dhcp server</param>
        /// <returns> true on if dhcp is supported.</returns>
        protected virtual bool HandleDHCP(IPPacket ipp)
        {
            UDPPacket udpp = new UDPPacket(ipp.Payload);
              DHCPPacket dhcp_packet = new DHCPPacket(udpp.Payload);
              MemBlock ether_addr = dhcp_packet.chaddr;

              if(_dhcp_config == null) {
            return true;
              }

              DHCPServer dhcp_server = CheckOutDHCPServer(ether_addr);
              if(dhcp_server == null) {
            return true;
              }

              MemBlock last_ip = null;
              _ether_to_ip.TryGetValue(ether_addr, out last_ip);
              byte[] last_ipb = (last_ip == null) ? null : (byte[]) last_ip;

              WaitCallback wcb = delegate(object o) {
            ProtocolLog.WriteIf(IpopLog.DHCPLog, String.Format(
            "Attemping DHCP for: {0}", Utils.MemBlockToString(ether_addr, '.')));

            DHCPPacket rpacket = null;
            try {
              rpacket = dhcp_server.ProcessPacket(dhcp_packet,
              Brunet.Address.ToString(), last_ipb);
            } catch(Exception e) {
              ProtocolLog.WriteIf(IpopLog.DHCPLog, e.Message);
              CheckInDHCPServer(dhcp_server);
              return;
            }

            /* Check our allocation to see if we're getting a new address */
            MemBlock new_addr = rpacket.yiaddr;
            UpdateMapping(ether_addr, new_addr);

            MemBlock destination_ip = ipp.SourceIP;
            if(destination_ip.Equals(IPPacket.ZeroAddress)) {
              destination_ip = IPPacket.BroadcastAddress;
            }

            UDPPacket res_udpp = new UDPPacket(_dhcp_server_port, _dhcp_client_port, rpacket.Packet);
            IPPacket res_ipp = new IPPacket(IPPacket.Protocols.UDP, rpacket.siaddr,
            destination_ip, res_udpp.ICPacket);
            EthernetPacket res_ep = new EthernetPacket(ether_addr, EthernetPacket.UnicastAddress,
            EthernetPacket.Types.IP, res_ipp.ICPacket);
            Ethernet.Send(res_ep.ICPacket);
            CheckInDHCPServer(dhcp_server);
              };

              ThreadPool.QueueUserWorkItem(wcb);
              return true;
        }
示例#4
0
文件: IpopNode.cs 项目: xujyan/ipop
        /// <summary>This method handles IPPackets that come from the TAP Device, i.e.,
        /// local system.</summary>
        /// <remarks>Currently this supports HandleMulticast (ip[0] >= 244 &&
        /// ip[0]<=239), HandleDNS (dport = 53 and ip[3] == 1), dhcp (sport 68 and
        /// dport 67.</remarks>
        /// <param name="packet">The packet from the TAP device</param>
        /// <param name="from"> This should always be the tap device</param>
        protected virtual void HandleIPOut(EthernetPacket packet, ISender ret)
        {
            IPPacket ipp = new IPPacket(packet.Payload);
              if(IpopLog.PacketLog.Enabled) {
            ProtocolLog.Write(IpopLog.PacketLog, String.Format(
                          "Outgoing {0} packet::IP src: {1}, IP dst: {2}",
                          ipp.Protocol, ipp.SSourceIP, ipp.SDestinationIP));
              }

              if(!IsLocalIP(ipp.SourceIP)) {
            HandleNewStaticIP(packet.SourceAddress, ipp.SourceIP);
            return;
              }

              if(ipp.DestinationIP[0] >= 224 && ipp.DestinationIP[0] <= 239) {
            if(HandleMulticast(ipp)) {
              return;
            }
              }

              switch(ipp.Protocol) {
            case IPPacket.Protocols.UDP:
              UDPPacket udpp = new UDPPacket(ipp.Payload);
              if(udpp.SourcePort == _dhcp_client_port && udpp.DestinationPort == _dhcp_server_port) {
            if(HandleDHCP(ipp)) {
              return;
            }
              } else if(udpp.DestinationPort == 53 &&ipp.DestinationIP.Equals(_dhcp_server.ServerIP)) {
            if(HandleDNS(ipp)) {
              return;
            }
              }
              break;
              }

              if(HandleOther(ipp)) {
            return;
              }

              if(_dhcp_server == null || ipp.DestinationIP.Equals(_dhcp_server.ServerIP)) {
            return;
              }

              AHAddress target = (AHAddress) _address_resolver.Resolve(ipp.DestinationIP);
              if (target != null) {
            if(IpopLog.PacketLog.Enabled) {
              ProtocolLog.Write(IpopLog.PacketLog, String.Format(
                            "Brunet destination ID: {0}", target));
            }
            SendIP(target, packet.Payload);
              }
        }
示例#5
0
文件: IpopNode.cs 项目: xujyan/ipop
        /// <summary>Parses ARP Packets and writes to the Ethernet the translation.</summary>
        /// <remarks>IpopRouter makes nodes think they are in the same Layer 2 network
        /// so that two nodes in the same network can communicate directly with each
        /// other.  IpopRouter masquerades for those that are not local.</remarks>
        /// <param name="ep">The Ethernet packet to translate</param>
        protected virtual void HandleARP(MemBlock packet)
        {
            // Can't do anything until we have network connectivity!
              if(_dhcp_server == null) {
            return;
              }

              ARPPacket ap = new ARPPacket(packet);

              // Not in our range!
              if(!_dhcp_server.IPInRange((byte[]) ap.TargetProtoAddress) &&
              !_dhcp_server.IPInRange((byte[]) ap.SenderProtoAddress))
              {
            ProtocolLog.WriteIf(IpopLog.ARP, String.Format("Bad ARP request from {0} for {1}",
            Utils.MemBlockToString(ap.SenderProtoAddress, '.'),
            Utils.MemBlockToString(ap.TargetProtoAddress, '.')));
            return;
              }

              if(ap.Operation == ARPPacket.Operations.Reply) {
            // This would be a unsolicited ARP
            if(ap.TargetProtoAddress.Equals(IPPacket.BroadcastAddress) &&
            !ap.SenderHWAddress.Equals(EthernetPacket.BroadcastAddress))
            {
              HandleNewStaticIP(ap.SenderHWAddress, ap.SenderProtoAddress);
            }
            return;
              }

              // We only support request operation hereafter
              if(ap.Operation != ARPPacket.Operations.Request) {
            return;
              }

              // Must return nothing if the node is checking availability of IPs
              // Or he is looking himself up.
              if(_ip_to_ether.ContainsKey(ap.TargetProtoAddress) ||
              ap.SenderProtoAddress.Equals(IPPacket.BroadcastAddress) ||
              ap.SenderProtoAddress.Equals(IPPacket.ZeroAddress))
              {
            return;
              }

              // We shouldn't be returning these messages if no one exists at that end
              // point
             if(!ap.TargetProtoAddress.Equals(MemBlock.Reference(_dhcp_server.ServerIP))) {
               Address baddr = _address_resolver.Resolve(ap.TargetProtoAddress);
               if(Brunet.Address.Equals(baddr) || baddr == null) {
             return;
               }
             }

             ProtocolLog.WriteIf(IpopLog.ARP, String.Format("Sending ARP response for: {0}",
             Utils.MemBlockToString(ap.TargetProtoAddress, '.')));

              ARPPacket response = ap.Respond(EthernetPacket.UnicastAddress);

              EthernetPacket res_ep = new EthernetPacket(ap.SenderHWAddress,
            EthernetPacket.UnicastAddress, EthernetPacket.Types.ARP,
            response.ICPacket);
              Ethernet.Send(res_ep.ICPacket);
        }
示例#6
0
文件: IpopNode.cs 项目: xujyan/ipop
        /// <summary> This method handles all incoming packets into the IpopNode, both
        /// abroad and local.  This is done to reduce unnecessary extra classes and
        /// circular dependencies.  This method probably shouldn't be called
        /// directly.</summary>
        /// <param name="b"> The incoming packet</param>
        /// <param name="ret">An ISender to return data from the original sender.</param>
        /// <param name="state">always will be null</param>
        public void HandleData(MemBlock b, ISender ret, object state)
        {
            if(ret is Ethernet) {
            EthernetPacket ep = new EthernetPacket(b);

            switch (ep.Type) {
              case EthernetPacket.Types.ARP:
            HandleARP(ep.Payload);
            break;
              case EthernetPacket.Types.IP:
            HandleIPOut(ep, ret);
            break;
            }
              }
              else {
            HandleIPIn(b, ret);
              }
        }
示例#7
0
    /// <summary>Writes an IPPacket as is to the TAP device.</summary>
    /// <param name="packet">The IPPacket!</param>
    protected virtual void WriteIP(ICopyable packet)
    {
      MemBlock mp = packet as MemBlock;
      if(mp == null) {
        mp = MemBlock.Copy(packet);
      }

      IPPacket ipp = new IPPacket(mp);
      MemBlock dest = null;
  
      if(!_ip_to_ether.TryGetValue(ipp.DestinationIP, out dest)) {
        if(ipp.DestinationIP[0] >= 224 && ipp.DestinationIP[0] <= 239) {
          dest = EthernetPacket.GetMulticastEthernetAddress(ipp.DestinationIP);
        } else if(ipp.DestinationIP[3] == 255){
          dest = EthernetPacket.BroadcastAddress;
        } else {
          return;
        }
      }

      EthernetPacket res_ep = new EthernetPacket(dest,
            EthernetPacket.UnicastAddress, EthernetPacket.Types.IP, mp);
      Ethernet.Send(res_ep.ICPacket);
    }
示例#8
0
    /// <summary>Parses Arp Packets and writes to the Ethernet the translation.</summary>
    /// <remarks>IpopRouter makes nodes think they are in the same Layer 2 network
    /// so that two nodes in the same network can communicate directly with each
    /// other.  IpopRouter masquerades for those that are not local.</remarks>
    /// <param name="ep">The Ethernet packet to translate</param>
    protected virtual void HandleArp(MemBlock packet)
    {
      // Can't do anything until we have network connectivity!
      if(_dhcp_server == null) {
        return;
      }

      ArpPacket ap = new ArpPacket(packet);

      // Not in our range!
      if(!_dhcp_server.IPInRange((byte[]) ap.TargetProtoAddress) &&
          !_dhcp_server.IPInRange((byte[]) ap.SenderProtoAddress))
      {
        ProtocolLog.WriteIf(IpopLog.Arp, String.Format("Bad Arp request from {0} for {1}",
            Utils.MemBlockToString(ap.SenderProtoAddress, '.'),
            Utils.MemBlockToString(ap.TargetProtoAddress, '.')));
        return;
      }


      if(ap.Operation == ArpPacket.Operations.Reply) {
        // This would be a unsolicited Arp
        if(ap.TargetProtoAddress.Equals(IPPacket.BroadcastAddress) &&
            !ap.SenderHWAddress.Equals(EthernetPacket.BroadcastAddress))
        {
          HandleNewStaticIP(ap.SenderHWAddress, ap.SenderProtoAddress);
        }
        return;
      }

      // We only support request operation hereafter
      if(ap.Operation != ArpPacket.Operations.Request) {
        return;
      }

      // Must return nothing if the node is checking availability of IPs
      // Or he is looking himself up.
      if(_ip_to_ether.ContainsKey(ap.TargetProtoAddress) ||
          ap.SenderProtoAddress.Equals(IPPacket.BroadcastAddress) ||
          ap.SenderProtoAddress.Equals(IPPacket.ZeroAddress))
      {
        return;
      }

      if(!ap.TargetProtoAddress.Equals(MemBlock.Reference(_dhcp_server.ServerIP))) {
        // Do not return messages if there is no connection to the remote address
        Address baddr = null;
        try {
          baddr = _address_resolver.Resolve(ap.TargetProtoAddress);
        } catch(AddressResolutionException ex) {
          if(ex.Issue != AddressResolutionException.Issues.DoesNotExist) {
            throw;
          }
          // Otherwise nothing to do, mapping doesn't exist...
        }

        if(AppNode.Node.Address.Equals(baddr) || baddr == null) {
          ProtocolLog.WriteIf(IpopLog.Arp, String.Format("No mapping for: {0}",
              Utils.MemBlockToString(ap.TargetProtoAddress, '.')));
          return;
        }

        if(!_conn_handler.ContainsAddress(baddr)) {
          ProtocolLog.WriteIf(IpopLog.Arp, String.Format(
              "No connection to {0} for {1}", baddr,
              Utils.MemBlockToString(ap.TargetProtoAddress, '.')));
          _conn_handler.ConnectTo(baddr);
          return;
        }
      }

      ProtocolLog.WriteIf(IpopLog.Arp, String.Format("Sending Arp response for: {0}",
        Utils.MemBlockToString(ap.TargetProtoAddress, '.')));

      ArpPacket response = ap.Respond(EthernetPacket.UnicastAddress);

      EthernetPacket res_ep = new EthernetPacket(ap.SenderHWAddress,
      EthernetPacket.UnicastAddress, EthernetPacket.Types.Arp,
      response.ICPacket);
      Ethernet.Send(res_ep.ICPacket);
    }
示例#9
0
    /// <summary>This method handles IPPackets that come from the TAP Device, i.e.,
    /// local system.</summary>
    /// <remarks>Currently this supports HandleMulticast (ip[0] >= 244 &&
    /// ip[0]<=239), HandleDns (dport = 53 and ip[3] == 1), dhcp (sport 68 and
    /// dport 67.</remarks>
    /// <param name="packet">The packet from the TAP device</param>
    /// <param name="from"> This should always be the tap device</param>
    protected virtual void HandleIPOut(EthernetPacket packet, ISender ret) {
      IPPacket ipp = new IPPacket(packet.Payload);

      if(IpopLog.PacketLog.Enabled) {
        ProtocolLog.Write(IpopLog.PacketLog, String.Format(
                          "Outgoing {0} packet::IP src: {1}, IP dst: {2}", 
                          ipp.Protocol, ipp.SSourceIP, ipp.SDestinationIP));
      }

      if(!IsLocalIP(ipp.SourceIP)) {
        // This really ought to have been caught in ARP, but just in case...
        HandleNewStaticIP(packet.SourceAddress, ipp.SourceIP);
        return;
      }

      UdpPacket udpp = null;
      switch(ipp.Protocol) {
        case IPPacket.Protocols.Udp:
          udpp = new UdpPacket(ipp.Payload);
          if(udpp.SourcePort == _dhcp_client_port && udpp.DestinationPort == _dhcp_server_port) {
            if(HandleDhcp(ipp)) {
              return;
            }
          } else if(udpp.DestinationPort == 53 && ipp.DestinationIP.Equals(_dhcp_server.ServerIP)) {
            if(HandleDns(ipp)) {
              return;
            }
          }
          break;
      }

      if(ipp.DestinationIP[0] >= 224 && ipp.DestinationIP[0] <= 239) {
        // We don't want to send Brunet multicast packets over IPOP!
        if(udpp != null && udpp.DestinationPort == IPHandler.mc_port) {
          return;
        } else if(HandleMulticast(ipp)) {
          return;
        }
      }

      if(ipp.DestinationIP.Equals(IPPacket.BroadcastAddress)) {
        if(HandleBroadcast(ipp)) {
          return;
        }
      }

      if(_dhcp_server == null || ipp.DestinationIP.Equals(_dhcp_server.ServerIP)) {
        return;
      }

      Address target = null;
      try {
        target = _address_resolver.Resolve(ipp.DestinationIP) as AHAddress;
      } catch(AddressResolutionException ex) {
        if(ex.Issue != AddressResolutionException.Issues.DoesNotExist) {
          throw;
        }
        // Otherwise nothing to do, mapping doesn't exist...
      }

      if(target != null) {
        SendIP(target, packet.Payload);
      }
    }