예제 #1
0
 public DHCPPacketView(DHCPMessageType messageType)
 {
     Packet             = new DHCPPacket();
     DHCPMessageType    = messageType;
     Hops               = 0;
     TimeElapsed        = TimeSpan.Zero;
     BroadcastFlag      = false;
     Packet.sname       = string.Empty;
     Packet.file        = string.Empty;
     Packet.magicNumber = DHCPPacket.DHCPMagicNumber;
     ClientIP           = IPAddress.Any;
     YourIP             = IPAddress.Any;
     NextServerIP       = IPAddress.Any;
     RelayAgentIP       = IPAddress.Any;
 }
예제 #2
0
 public DHCPPacketView(DHCPPacket packet)
 {
     Packet = packet;
 }
예제 #3
0
 public DHCPPacketView(byte[] buffer)
 {
     Packet = DHCPPacketParser.Parse(buffer);
 }
예제 #4
0
        /// <summary>
        /// DHCP packet parser based on RFC2131 (https://tools.ietf.org/html/rfc2131)
        /// </summary>
        /// <param name="buffer">The input buffer to parse.</param>
        /// <returns>A parsed packet structure or null</returns>
        public static DHCPPacket Parse(byte[] buffer)
        {
            if (buffer.Length < 240)
            {
                throw new ArgumentException("The minimum DHCP packet size if 236 bytes", "buffer");
            }

            // Parse BOOTP Options
            var result = new DHCPPacket
            {
                op          = (MessageOpCode)buffer[0],
                htype       = (HardwareAddressType)buffer[1],
                hlen        = Convert.ToInt32(buffer[2]),
                hops        = Convert.ToInt32(buffer[3]),
                xid         = Read32UnsignedBE(buffer, 4),
                secs        = Convert.ToInt32(Read16UnsignedBE(buffer, 8)),
                flags       = Convert.ToInt32(Read16UnsignedBE(buffer, 10)),
                ciaddr      = ReadIPAddress(buffer, 12),
                yiaddr      = ReadIPAddress(buffer, 16),
                siaddr      = ReadIPAddress(buffer, 20),
                giaddr      = ReadIPAddress(buffer, 24),
                chaddr      = ReadClientHardwareAddress((HardwareAddressType)buffer[1], buffer, 28),
                sname       = Encoding.ASCII.GetString(buffer, 44, 64).Trim(),
                file        = Encoding.ASCII.GetString(buffer, 108, 128).Trim(),
                magicNumber = Read32UnsignedBE(buffer, 236)
            };

            if (result.magicNumber != DHCPPacket.DHCPMagicNumber)
            {
                throw new Exception("Received packet may be a BOOTP packet but is not a valid DHCP packet as it is missing the magic number at offset 236.");
            }

            var index = 240;

            while (index < buffer.Length)
            {
                int optionCode = Convert.ToInt32(buffer[index++]);
                if ((DHCPOptionType)optionCode == DHCPOptionType.End)
                {
                    break;
                }

                int length = Convert.ToInt32(buffer[index++]);

                // Parse the new option and add it to the list
                var dhcpOption = ParseDHCPOption(optionCode, length, buffer, index);
                result.options.Add(dhcpOption);
                index += length;

                // For option 43 (Vendor Specific Information) and 60 (Vendor Class Id),
                // there is a "chicken and egg" possibility. As such, if 43 is seen before
                // 60 is seen, then the suboptions will be parsed before knowing the vendor class.
                // Then when option 60 is seen, option 43 will be reprocessed to find the right suboptions.
                if (dhcpOption is DHCPOptionVendorSpecificInformation)
                {
                    (dhcpOption as DHCPOptionVendorSpecificInformation).VendorClassId = GetVendorClassId(result.options);
                }
                else if (dhcpOption is DHCPOptionClassId)
                {
                    SetVendorClassId(result.options, (dhcpOption as DHCPOptionClassId).ClassId);
                }
            }

            return(result);
        }