示例#1
0
        /// <summary>
        /// Creates a new instance of this class by parsing the given data
        /// </summary>
        /// <param name="bData">The data to parse</param>
        public DHCPFrame(byte[] bData)
        {
            byte[] bAddressBytes = new byte[4];
            byte[] bMacBytes     = new byte[6];
            lTLVs = new List <DHCPTLVItem>();
            DHCPTLVItem dhcpItem;

            dhtMessageType  = (DHCPType)bData[0];
            dhtHardwareType = (HardwareAddressType)bData[1];
            sHardwarelen    = (short)bData[2];
            sHops           = (short)bData[3];
            iTransactionID  = BitConverter.ToInt32(bData, 4);
            iSecs           = BitConverter.ToInt16(bData, 8);
            bValidIPFlag    = (bData[10] & 0x80) == 1;

            for (int iC1 = 0; iC1 < 4; iC1++)
            {
                bAddressBytes[iC1] = bData[12 + iC1];
            }
            ipaClientAddress = new IPAddress(bAddressBytes);

            for (int iC1 = 0; iC1 < 4; iC1++)
            {
                bAddressBytes[iC1] = bData[16 + iC1];
            }
            ipaOwnAddress = new IPAddress(bAddressBytes);

            for (int iC1 = 0; iC1 < 4; iC1++)
            {
                bAddressBytes[iC1] = bData[20 + iC1];
            }
            ipaServerAddress = new IPAddress(bAddressBytes);

            for (int iC1 = 0; iC1 < 4; iC1++)
            {
                bAddressBytes[iC1] = bData[24 + iC1];
            }
            ipaRelayAddress = new IPAddress(bAddressBytes);

            for (int iC1 = 0; iC1 < 6; iC1++)
            {
                bMacBytes[iC1] = bData[28 + iC1];
            }
            macClientMac = new MACAddress(bMacBytes);

            strRequestedServerName = Encoding.ASCII.GetString(bData, 34, 64).Trim(new char[] { '\0' });
            strRequestedFile       = Encoding.ASCII.GetString(bData, 98, 128).Trim(new char[] { '\0' });

            if (bData[236] != 0x63 || bData[237] != 0x82 || bData[238] != 0x53 || bData[239] != 0x63)
            {
                throw new Exception("Invalid DHCP magic number");
            }

            int iC2 = 240;

            while (iC2 < bData.Length)
            {
                if (bData[iC2] == (int)DHCPOptions.End)
                {
                    break;
                }
                dhcpItem = new DHCPTLVItem(bData, iC2);
                lTLVs.Add(dhcpItem);
                iC2 += dhcpItem.Length;
            }
        }
示例#2
0
 /// <summary>
 /// Checks whether a specific TLV item is contained in this instance
 /// </summary>
 /// <param name="dhItem">The TLV item to search for</param>
 /// <returns>A bool indicating whether a specific TLV item is contained in this instance</returns>
 public bool ContainsDHCPTLVItem(DHCPTLVItem dhItem)
 {
     return(lTLVs.Contains(dhItem));
 }
示例#3
0
 /// <summary>
 /// Adds a TLV item to this instance
 /// </summary>
 /// <param name="dhItem">The TLV item to add</param>
 public void AddDHCPTLVItem(DHCPTLVItem dhItem)
 {
     lTLVs.Add(dhItem);
 }
示例#4
0
 /// <summary>
 /// Removes a specific TLV item from this instance
 /// </summary>
 /// <param name="dhItem">The TLV item to remove</param>
 public void RemoveDHCPTLVItem(DHCPTLVItem dhItem)
 {
     lTLVs.Remove(dhItem);
 }
示例#5
0
        /// <summary>
        /// Handles a DHCP frame and sends responses or leases addresses according to its contents
        /// </summary>
        /// <param name="dhcFrame">The DHCP frame to handle</param>
        /// <param name="udpFrame">The UDP frame</param>
        /// <param name="ipFrame">The IP frame</param>
        /// <param name="tdf">The traffic description frame</param>
        /// <param name="fInputFrame">The original root frame</param>
        protected virtual void HandleDHCPFrame(DHCPFrame dhcFrame, eExNetworkLibrary.UDP.UDPFrame udpFrame, eExNetworkLibrary.IP.IPFrame ipFrame, TrafficDescriptionFrame tdf, Frame fInputFrame)
        {
            bool bIsRequest  = false;
            bool bIsDiscover = false;

            foreach (DHCPTLVItem tlvItem in dhcFrame.GetDHCPTLVItems())
            {
                if (tlvItem.DHCPOptionType == DHCPOptions.DHCPMessageType)
                {
                    if (dhcFrame.MessageType == DHCPType.BootRequest && (DHCPMessageType)tlvItem.Data[0] == DHCPMessageType.Discover)
                    {
                        bIsDiscover = true;
                        break;
                    }
                    if (dhcFrame.MessageType == DHCPType.BootRequest && (DHCPMessageType)tlvItem.Data[0] == DHCPMessageType.Request && lOpenServerTransactions.Contains(dhcFrame.TransactionID))
                    {
                        bIsRequest = true;
                        break;
                    }
                }
            }

            if (bIsRequest)
            {
                #region Server Process request

                MACAddress mClientID = dhcFrame.ClientMac;

                if (tdf != null && tdf.SourceInterface != null)
                {
                    if (dictInterfacePool.ContainsKey(tdf.SourceInterface))
                    {
                        IPAddress ipaAddressRequestet = IPAddress.Any;
                        string    strHostname         = "";

                        foreach (DHCPTLVItem tlvItemSearch in dhcFrame.GetDHCPTLVItems())
                        {
                            if (tlvItemSearch.DHCPOptionType == DHCPOptions.AddressRequest)
                            {
                                ipaAddressRequestet = new IPAddress(tlvItemSearch.Data);
                            }
                            if (tlvItemSearch.DHCPOptionType == DHCPOptions.Hostname)
                            {
                                strHostname = ASCIIEncoding.ASCII.GetString(tlvItemSearch.Data);
                            }
                        }

                        DHCPPool     dhPool = dictInterfacePool[tdf.SourceInterface];
                        DHCPPoolItem dhItem = dhPool.GetItemForAddress(ipaAddressRequestet);

                        if (dhItem != null)
                        {
                            IPAddress ipaServer      = tdf.SourceInterface.IpAddresses[0];
                            IPAddress offeredAddress = dhItem.Address;

                            DHCPFrame newDHCPFrame = new DHCPFrame();
                            newDHCPFrame.ClientAddress       = IPAddress.Any;
                            newDHCPFrame.ClientMac           = mClientID;
                            newDHCPFrame.Hardwarelen         = 6;
                            newDHCPFrame.HardwareType        = eExNetworkLibrary.HardwareAddressType.Ethernet;
                            newDHCPFrame.Hops                = 0;
                            newDHCPFrame.MessageType         = DHCPType.BootReply;
                            newDHCPFrame.OfferedAddress      = offeredAddress;
                            newDHCPFrame.RelayAddress        = IPAddress.Any;
                            newDHCPFrame.RequestedFile       = "";
                            newDHCPFrame.RequestedServerName = "";
                            newDHCPFrame.Secs                = dhcFrame.Secs + 1;
                            newDHCPFrame.ServerAddress       = ipaServer;
                            newDHCPFrame.ValidIPFlag         = true;
                            newDHCPFrame.TransactionID       = dhcFrame.TransactionID;

                            DHCPTLVItem tlvItem = new DHCPTLVItem();
                            tlvItem.DHCPOptionType = DHCPOptions.DHCPMessageType;
                            tlvItem.Data           = new byte[] { (byte)DHCPMessageType.ACK };

                            newDHCPFrame.AddDHCPTLVItem(tlvItem);

                            tlvItem = new DHCPTLVItem();
                            tlvItem.DHCPOptionType = DHCPOptions.ClientID;
                            byte[] bIDData = new byte[7];
                            bIDData[0] = (byte)HardwareAddressType.Ethernet;
                            mClientID.AddressBytes.CopyTo(bIDData, 1);
                            tlvItem.Data = bIDData;

                            newDHCPFrame.AddDHCPTLVItem(tlvItem);

                            tlvItem = new DHCPTLVItem();
                            tlvItem.DHCPOptionType = DHCPOptions.SubnetMask;
                            tlvItem.Data           = dhItem.Netmask.MaskBytes;

                            newDHCPFrame.AddDHCPTLVItem(tlvItem);

                            tlvItem = new DHCPTLVItem();
                            tlvItem.DHCPOptionType = DHCPOptions.Router;
                            tlvItem.Data           = dhItem.Gateway.GetAddressBytes();

                            newDHCPFrame.AddDHCPTLVItem(tlvItem);

                            tlvItem = new DHCPTLVItem();
                            tlvItem.DHCPOptionType = DHCPOptions.DomainNameServer;
                            tlvItem.Data           = dhItem.DNSServer.GetAddressBytes();

                            newDHCPFrame.AddDHCPTLVItem(tlvItem);

                            tlvItem = new DHCPTLVItem();
                            tlvItem.DHCPOptionType = DHCPOptions.LeaseTime;
                            tlvItem.Data           = BitConverter.GetBytes(iLeaseDuration);

                            newDHCPFrame.AddDHCPTLVItem(tlvItem);

                            tlvItem = new DHCPTLVItem();
                            tlvItem.DHCPOptionType = DHCPOptions.DHCPServerID;
                            tlvItem.Data           = ipaServer.GetAddressBytes();

                            newDHCPFrame.AddDHCPTLVItem(tlvItem);

                            UDP.UDPFrame newUDPFrame = new eExNetworkLibrary.UDP.UDPFrame();
                            newUDPFrame.DestinationPort   = iDHCPInPort;
                            newUDPFrame.SourcePort        = iDHCPOutPort;
                            newUDPFrame.EncapsulatedFrame = newDHCPFrame;

                            IP.IPv4Frame newIPv4Frame = new eExNetworkLibrary.IP.IPv4Frame();
                            newIPv4Frame.Version            = 4;
                            newIPv4Frame.DestinationAddress = IPAddress.Broadcast;
                            newIPv4Frame.SourceAddress      = ipaServer;
                            newIPv4Frame.Protocol           = eExNetworkLibrary.IP.IPProtocol.UDP;
                            newIPv4Frame.EncapsulatedFrame  = newUDPFrame;
                            newIPv4Frame.Identification     = (uint)IncrementIPIDCounter();
                            newIPv4Frame.TimeToLive         = 128;

                            TrafficDescriptionFrame tdFrame = new TrafficDescriptionFrame(null, DateTime.Now);
                            tdFrame.EncapsulatedFrame = newIPv4Frame;

                            tdf.SourceInterface.Send(tdFrame, IPAddress.Broadcast);
                            dhItem.LeasedTo         = mClientID;
                            dhItem.LeasedToHostname = strHostname;
                            dhItem.LeaseDuration    = new TimeSpan(0, 0, 0, iLeaseDuration, 0);
                            lOpenServerTransactions.Remove(newDHCPFrame.TransactionID);
                            InvokeAddressLeased(new DHCPServerEventArgs(dhPool, dhItem, tdf.SourceInterface));
                        }
                    }
                }

                #endregion
            }
            else if (bIsDiscover)
            {
                #region Server Process discover

                MACAddress mClientID = dhcFrame.ClientMac;

                if (tdf != null && tdf.SourceInterface != null)
                {
                    if (dictInterfacePool.ContainsKey(tdf.SourceInterface))
                    {
                        DHCPPool     dhPool = dictInterfacePool[tdf.SourceInterface];
                        DHCPPoolItem dhItem = dhPool.GetNextFreeAddress();

                        if (dhItem != null)
                        {
                            IPAddress ipaServer      = tdf.SourceInterface.IpAddresses[0];
                            IPAddress offeredAddress = dhItem.Address;

                            DHCPFrame newDHCPFrame = new DHCPFrame();
                            newDHCPFrame.ClientAddress       = IPAddress.Any;
                            newDHCPFrame.ClientMac           = mClientID;
                            newDHCPFrame.Hardwarelen         = 6;
                            newDHCPFrame.HardwareType        = eExNetworkLibrary.HardwareAddressType.Ethernet;
                            newDHCPFrame.Hops                = 0;
                            newDHCPFrame.MessageType         = DHCPType.BootReply;
                            newDHCPFrame.OfferedAddress      = offeredAddress;
                            newDHCPFrame.RelayAddress        = IPAddress.Any;
                            newDHCPFrame.RequestedFile       = "";
                            newDHCPFrame.RequestedServerName = "";
                            newDHCPFrame.Secs                = dhcFrame.Secs + 1;
                            newDHCPFrame.ServerAddress       = ipaServer;
                            newDHCPFrame.ValidIPFlag         = true;
                            newDHCPFrame.TransactionID       = dhcFrame.TransactionID;

                            DHCPTLVItem tlvItem = new DHCPTLVItem();
                            tlvItem.DHCPOptionType = DHCPOptions.DHCPMessageType;
                            tlvItem.Data           = new byte[] { (byte)DHCPMessageType.Offer };

                            newDHCPFrame.AddDHCPTLVItem(tlvItem);

                            tlvItem = new DHCPTLVItem();
                            tlvItem.DHCPOptionType = DHCPOptions.ClientID;
                            byte[] bIDData = new byte[7];
                            bIDData[0] = (byte)HardwareAddressType.Ethernet;
                            mClientID.AddressBytes.CopyTo(bIDData, 1);
                            tlvItem.Data = bIDData;

                            newDHCPFrame.AddDHCPTLVItem(tlvItem);

                            tlvItem = new DHCPTLVItem();
                            tlvItem.DHCPOptionType = DHCPOptions.SubnetMask;
                            tlvItem.Data           = dhItem.Netmask.MaskBytes;

                            newDHCPFrame.AddDHCPTLVItem(tlvItem);

                            tlvItem = new DHCPTLVItem();
                            tlvItem.DHCPOptionType = DHCPOptions.Router;
                            tlvItem.Data           = dhItem.Gateway.GetAddressBytes();

                            newDHCPFrame.AddDHCPTLVItem(tlvItem);

                            tlvItem = new DHCPTLVItem();
                            tlvItem.DHCPOptionType = DHCPOptions.DomainNameServer;
                            tlvItem.Data           = dhItem.DNSServer.GetAddressBytes();

                            newDHCPFrame.AddDHCPTLVItem(tlvItem);

                            tlvItem = new DHCPTLVItem();
                            tlvItem.DHCPOptionType = DHCPOptions.LeaseTime;
                            tlvItem.Data           = BitConverter.GetBytes(86400);

                            newDHCPFrame.AddDHCPTLVItem(tlvItem);

                            tlvItem = new DHCPTLVItem();
                            tlvItem.DHCPOptionType = DHCPOptions.DHCPServerID;
                            tlvItem.Data           = ipaServer.GetAddressBytes();

                            newDHCPFrame.AddDHCPTLVItem(tlvItem);

                            UDP.UDPFrame newUDPFrame = new eExNetworkLibrary.UDP.UDPFrame();
                            newUDPFrame.DestinationPort   = iDHCPInPort;
                            newUDPFrame.SourcePort        = iDHCPOutPort;
                            newUDPFrame.EncapsulatedFrame = newDHCPFrame;

                            IP.IPv4Frame newIPv4Frame = new eExNetworkLibrary.IP.IPv4Frame();
                            newIPv4Frame.Version            = 4;
                            newIPv4Frame.DestinationAddress = IPAddress.Broadcast;
                            newIPv4Frame.SourceAddress      = ipaServer;
                            newIPv4Frame.Protocol           = eExNetworkLibrary.IP.IPProtocol.UDP;
                            newIPv4Frame.EncapsulatedFrame  = newUDPFrame;
                            newIPv4Frame.Identification     = (uint)IncrementIPIDCounter();
                            newIPv4Frame.TimeToLive         = 128;

                            TrafficDescriptionFrame tdFrame = new TrafficDescriptionFrame(null, DateTime.Now);
                            tdFrame.EncapsulatedFrame = newIPv4Frame;

                            tdf.SourceInterface.Send(tdFrame, IPAddress.Broadcast);
                            lOpenServerTransactions.Add(newDHCPFrame.TransactionID);
                        }
                    }
                }

                #endregion
            }
        }