Encapsulates a Dhcp Packet in an immutable object providing both a byte array and a parsed version of the dhcp information
The outline of a Dhcp Packet: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | op (1) | htype (1) | hlen (1) | hops (1) | +---------------+---------------+---------------+---------------+ | xid (4) | +-------------------------------+-------------------------------+ | secs (2) | flags (2) | +-------------------------------+-------------------------------+ | ciaddr (4) | +---------------------------------------------------------------+ | yiaddr (4) | +---------------------------------------------------------------+ | siaddr (4) | +---------------------------------------------------------------+ | giaddr (4) | +---------------------------------------------------------------+ | | | chaddr (16) | | | | | +---------------------------------------------------------------+ | | | sname (64) | +---------------------------------------------------------------+ | | | file (128) | +---------------------------------------------------------------+ | | | options (variable) | +---------------------------------------------------------------+ Field Description OP 1 for request, 2 for response htype hardware address type - leave at 1 hlen hardware address length - 6 for ethernet mac address hops optional - leave at 0, no relay agents xid transaction id secs seconds since beginning renewal flags ciaddr clients currrent ip (client in bound, renew, or rebinding state) yiaddr ip address server is giving to client siaddr server address giaddr leave at zero, no relay agents chaddr client hardware address sname optional server hostname file optional magic cookie yuuuum! - byte[4] = {99, 130, 83, 99} options starts at 240!
Inheritance: DataPacket
Example #1
0
        /// <summary></summary>
        public DhcpPacket ProcessPacket(DhcpPacket packet, string unique_id,
        byte[] last_ip, params object[] dhcp_params)
        {
            DhcpPacket.MessageTypes message_type = (DhcpPacket.MessageTypes)
                                  packet.Options[DhcpPacket.OptionTypes.MESSAGE_TYPE][0];

              byte[] requested_ip = last_ip;
              bool renew = false;

              if(message_type == DhcpPacket.MessageTypes.DISCOVER) {
            message_type = DhcpPacket.MessageTypes.OFFER;
              } else if(message_type == DhcpPacket.MessageTypes.REQUEST) {
            if(packet.Options.ContainsKey(DhcpPacket.OptionTypes.REQUESTED_IP)) {
              requested_ip = packet.Options[DhcpPacket.OptionTypes.REQUESTED_IP];
            } else if(!packet.ciaddr.Equals(IPPacket.ZeroAddress)) {
              requested_ip = packet.ciaddr;
            }
            renew = true;
            message_type = DhcpPacket.MessageTypes.ACK;
              } else {
            throw new Exception("Unsupported message type!");
              }

              byte[] reply_ip = RequestLease(requested_ip, renew, unique_id, dhcp_params);

              Dictionary<DhcpPacket.OptionTypes, MemBlock> options =
            new Dictionary<DhcpPacket.OptionTypes, MemBlock>();

              options[DhcpPacket.OptionTypes.DOMAIN_NAME] = Encoding.UTF8.GetBytes(Dns.DomainName);
            //  The following option is needed for dhcp to "succeed" in Vista, but they break Linux
            //    options[DhcpPacket.OptionTypes.ROUTER] = reply.ip;
              options[DhcpPacket.OptionTypes.DOMAIN_NAME_SERVER] = MemBlock.Reference(ServerIP);
              options[DhcpPacket.OptionTypes.SUBNET_MASK] = MemBlock.Reference(Netmask);
              options[DhcpPacket.OptionTypes.LEASE_TIME] = _lease_time;
              options[DhcpPacket.OptionTypes.MTU] = _mtu;
              options[DhcpPacket.OptionTypes.SERVER_ID] = MemBlock.Reference(ServerIP);
              options[DhcpPacket.OptionTypes.MESSAGE_TYPE] = MemBlock.Reference(new byte[]{(byte) message_type});
              DhcpPacket rpacket = new DhcpPacket(2, packet.xid, packet.ciaddr, reply_ip,
                               ServerIP, packet.chaddr, options);
              return rpacket;
        }
Example #2
0
    /// <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(
            "Attempting Dhcp for: {0}", Utils.MemBlockToString(ether_addr, '.')));

        DhcpPacket rpacket = null;
        try {
          rpacket = dhcp_server.ProcessPacket(dhcp_packet,
              AppNode.Node.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;
    }