Пример #1
0
        internal override void EnterEvent()
        {
            client.SetStateTimeout(DateTime.Now + StateTimeout);

            DhcpFormat dhcp =
                new DhcpFormat(DhcpFormat.MessageType.Request);

            dhcp.TransactionID      = client.TransactionID;
            dhcp.TransactionSeconds = client.TransactionSeconds;
            dhcp.SetHardwareAddress(client.MacAddress);
#if ADVERTISE_CLIENT_ID
            dhcp.AddOption(
                DhcpClientID.Create(client.MacAddress.GetAddressBytes())
                );
#endif
            dhcp.AddOption(
                DhcpRequestedIPAddress.Create(offeredAddress)
                );

            // Add parameters we'd like to know about
            dhcp.AddOption(DhcpParameterRequest.Create(
                               DhcpClient.StandardRequestParameters
                               )
                           );

            client.Send(EthernetAddress.Broadcast, dhcp);
        }
Пример #2
0
        internal override void EnterEvent()
        {
            client.StartNewTransaction();

            DhcpFormat dhcp =
                new DhcpFormat(DhcpFormat.MessageType.Discover);

            dhcp.TransactionID = client.TransactionID;
            dhcp.SetHardwareAddress(client.MacAddress);

#if ADVERTISE_CLIENT_ID
            // Add Client Identifier for self
            //
            // [2006-02-03 ohodson] This is disabled because the Windows
            // DHCP server allocates us a different address with the
            // client id present if we networked booted.  Thus having the
            // identifier breaks static DHCP entries which we use
            // for test machines.
            EthernetAddress macAddress = client.MacAddress;
            dhcp.AddOption(DhcpClientID.Create(macAddress.GetAddressBytes()));
#endif

            // Add parameters we'd like to know about
            dhcp.AddOption(DhcpParameterRequest.Create(
                               DhcpClient.StandardRequestParameters
                               )
                           );
            // dhcp.AddOption(DhcpAutoConfigure.Create(0));
            client.Send(EthernetAddress.Broadcast, dhcp);
            client.ChangeState(new DhcpClientStateSelecting(client));
        }
Пример #3
0
        internal override void ReceiveEvent(DhcpFormat dhcp)
        {
            //DebugStub.WriteLine("FSM DHCP packet SELECTING.\n");

            // Check if message is in response to our request
            if (dhcp.BootMessageType != DhcpFormat.BootType.Reply ||
                dhcp.TransactionID != client.TransactionID ||
                dhcp.GetHardwareAddress() != client.MacAddress)
            {
                DebugStub.WriteLine("FSM DHCP bad id.\n");
                return;
            }

            IPv4 serverAddress = dhcp.NextServerIPAddress;

            // Check if offered address is valid (ie not zero
            // and below class E)
            IPv4 offeredAddress = dhcp.YourIPAddress;

            if (offeredAddress == IPv4.Any || offeredAddress.IsMulticast())
            {
                DebugStub.WriteLine("FSM DHCP multicast addr.\n");
                return;
            }

            // Check if message is an offer
            SortedList     offeredOptions = dhcp.GetOptions();
            DhcpByteOption messageType
                = offeredOptions[DhcpMessageType.OptionCode] as DhcpByteOption;

            if (messageType == null ||
                messageType.Value != (byte)DhcpFormat.MessageType.Offer)
            {
                DebugStub.WriteLine("FSM DHCP not an offer.\n");
                return;
            }

            // Must have parameters
            byte [] parameters = new byte [] {
                DhcpSubnetMask.OptionCode,
                DhcpRouter.OptionCode,
                // DhcpDomainNameServer.OptionCode
            };

            foreach (byte p in parameters)
            {
                IDhcpOption ido = offeredOptions[p] as IDhcpOption;
                if (ido == null)
                {
                    DebugStub.WriteLine("FSM DHCP missing option 0x{0:x2}.\n", DebugStub.ArgList(p));
                    return;
                }
            }

            client.CancelStateTimeout();
            client.ChangeState(new DhcpClientStateRequesting(client,
                                                             serverAddress,
                                                             offeredAddress,
                                                             offeredOptions));
        }
Пример #4
0
        private static void TakeOption(SortedList offeredOptions,
                                       byte optionCode,
                                       DhcpFormat dhcpFormat)
        {
            IDhcpOption option = offeredOptions[optionCode] as IDhcpOption;

            if (option != null)
            {
                dhcpFormat.AddOption(option);
            }
        }
Пример #5
0
        internal bool Send(EthernetAddress dstAddr, DhcpFormat dhcp)
        {
            int   packetSize = dhcp.Size;
            int   headerSize = EthernetHeader.Size + UDPHeader.Size + IpHeader.Size;
            Bytes packet     = new Bytes(new byte [packetSize]);
            Bytes header     = new Bytes(new byte [headerSize]);

            // Write out DHCP packet
            dhcp.Write(packet, 0);
            //the correct ports/addresses should already be bound up in instance of the UDP object
            udp.WriteCompleteUDPHeader(header, packet, dhcp.Size);
            // Add Ethernet Header
            EthernetHeader.Write(header, adapter.HardwareAddress,
                                 dstAddr, EthernetHeader.PROTOCOL_IP);
            adapter.PopulateTxRing(header, packet);
            return(true);
        }
Пример #6
0
 /// <summary>
 /// State should process that has arrived.
 /// </summary>
 internal virtual void ReceiveEvent(DhcpFormat df)
 {
     //DebugStub.WriteLine("FSM Ignored DHCP packet: {0}\n", DebugStub.ArgList(stateName));
 }
Пример #7
0
 internal override void ReceiveEvent(DhcpFormat dhcp)
 {
     //DebugStub.WriteLine("FSM DHCP packet REBINDING.\n");
 }
Пример #8
0
 internal override void ReceiveEvent(DhcpFormat dhcp)
 {
     //DebugStub.WriteLine("FSM DHCP packet BOUND.\n");
     // ignore
 }
Пример #9
0
        internal override void ReceiveEvent(DhcpFormat dhcp)
        {
            //DebugStub.WriteLine("FSM DHCP packet REQUESTING.\n");

            // Check if message is in response to our request
            if (dhcp.BootMessageType != DhcpFormat.BootType.Reply ||
                dhcp.TransactionID != client.TransactionID ||
                dhcp.GetHardwareAddress() != client.MacAddress)
            {
                return;
            }

            IPv4 serverAddress = dhcp.NextServerIPAddress;

            // Check if offered address is valid (ie not zero
            // and below class E)
            IPv4 offeredAddress = dhcp.YourIPAddress;

            if (offeredAddress == IPv4.Any || offeredAddress.IsMulticast())
            {
                return;
            }

            // Check if message is an ack
            SortedList     offeredOptions = dhcp.GetOptions();
            DhcpByteOption messageType
                = offeredOptions[DhcpMessageType.OptionCode] as DhcpByteOption;

            if (messageType == null)
            {
                return;
            }

            switch (messageType.Value)
            {
            case (byte)DhcpFormat.MessageType.Ack:
                break;

            case (byte)DhcpFormat.MessageType.Nak:
                client.ChangeState(new DhcpClientStateInitialize(client));
                return;

            default:
                return;
            }

            // Must have parameters
            byte [] parameters = new byte [] {
                DhcpSubnetMask.OptionCode,
                DhcpRouter.OptionCode,
                // DhcpDomainNameServer.OptionCode
            };

            foreach (byte p in parameters)
            {
                IDhcpOption ido = offeredOptions[p] as IDhcpOption;
                if (ido == null)
                {
                    return;
                }
            }

            client.CancelStateTimeout();
            client.ChangeState(new DhcpClientStateBound(client,
                                                        serverAddress,
                                                        offeredAddress,
                                                        offeredOptions));
        }
Пример #10
0
        private void WorkerMain()
        {
            DebugPrint("Worker starting\n");

            //TODO: Random r = new Random();
            //TODO: transactionID = (uint)r.Next();
            transactionID = (uint)INucleusCalls.Rdtsc();
            DateTime startTime = DateTime.Now;

            // Enter "Init" state of FSM
            ChangeState(new DhcpClientStateInitialize(this));

            while (workerDone == false)
            {
                // Check for timeouts
                DateTime now = DateTime.Now;
                if (now >= renewalTimeout)
                {
                    CancelRenewalTimeout();
                    @state.RenewalTimeoutEvent();
                }
                if (now >= rebindTimeout)
                {
                    CancelRebindTimeout();
                    @state.RebindTimeoutEvent();
                }
                if (now >= stateTimeout)
                {
                    CancelStateTimeout();
                    @state.StateTimeoutEvent();
                }

                // Poll for data
                try {
                    Bytes data = udp.PollReadData(PollInterval);
                    if (data != null)
                    {
                        DhcpFormat dhcp = DhcpFormat.Parse(data);
                        //delete data;
                        // Check transaction id is ours
                        if (dhcp.TransactionID != transactionID)
                        {
                            continue;
                        }

                        // Check client address is ours
                        if (dhcp.GetHardwareAddress() != MacAddress)
                        {
                            continue;
                        }

                        @state.ReceiveEvent(dhcp);
                    }
                }
                catch (InvalidDhcpFormatException idfe) {
                    DebugPrint(idfe.Message);
                }

                // XXX Temporary until process can run in background
                // from shell.  ie we'd like to run and renew lease
                // but shell blocks on running process and cleans up
                // after it for the time being.
                if (activeDhcpOptions != null)
                {
                    DebugPrint("Got options -- done\n");
                    break;
                }

                if (DateTime.Now - startTime > TimeSpan.FromSeconds(5))
                {
                    DebugPrint("Timed out\n");
                    break;
                }
            }
        }
Пример #11
0
        public static DhcpFormat Parse(Bytes buffer)
        {
            DhcpFormat p = new DhcpFormat(BootType.NotSpecified);

            p.optionsUsedLength = 0;

            if (buffer.Length < DhcpFormat.MinLength)
            {
                throw new InvalidDhcpFormatException("Format less than minimum size");
            }
            int offset = 0;

            p.op = buffer[offset++];
            if (p.op != (byte)BootType.Request &&
                p.op != (byte)BootType.Reply)
            {
                throw new InvalidDhcpFormatException("Bad Type (op = {0})", p.op);
            }
            p.htype = buffer[offset++];
            // No check

            p.hlen = buffer[offset++];
            if (p.hlen > HardwareAddressLength)
            {
                throw new InvalidDhcpFormatException("Bad address length (hlen {0})",
                                                     p.hlen);
            }
            p.hops = buffer[offset++];
            // No check

            p.xid   = NetworkBitConverter.ToUInt32(buffer, offset);
            offset += 4;

            p.secs  = NetworkBitConverter.ToUInt16(buffer, offset);
            offset += 2;

            p.flags = NetworkBitConverter.ToUInt16(buffer, offset);
            offset += 2;

            p.ciaddr = NetworkBitConverter.ToUInt32(buffer, offset);
            offset  += 4;

            p.yiaddr = NetworkBitConverter.ToUInt32(buffer, offset);
            offset  += 4;

            p.siaddr = NetworkBitConverter.ToUInt32(buffer, offset);
            offset  += 4;

            p.giaddr = NetworkBitConverter.ToUInt32(buffer, offset);
            offset  += 4;

            Bitter.ToByteArray(buffer, offset, HardwareAddressLength, p.chaddr, 0);
            offset += HardwareAddressLength;
            Bitter.ToByteArray(buffer, offset, ServerNameLength, p.sname, 0);
            offset += ServerNameLength;
            Bitter.ToByteArray(buffer, offset, BootFileLength, p.file, 0);
            offset += BootFileLength;

            p.cookie = NetworkBitConverter.ToUInt32(buffer, offset);
            offset  += 4;
            if (p.cookie != DhcpCookie)
            {
                throw new InvalidDhcpFormatException("Bad cookie (0x{0x:x8})",
                                                     p.cookie);
            }
            int available = buffer.Length - offset;

            if (available > p.options.Length)
            {
                p.options = new byte [available];
            }
            p.optionsUsedLength = available;
            Bitter.ToByteArray(buffer, offset, available, p.options, 0);

            return(p);
        }