示例#1
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
            //
            // 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));
        }
        private void Respond(DhcpFormat request, DhcpFormat.MessageType m)
        {
            DhcpFormat response = new DhcpFormat(m);

            response.TransactionID = request.TransactionID;

            EthernetAddress hwAddress = request.GetHardwareAddress();

            response.SetHardwareAddress(hwAddress);

            switch (m)
            {
            case DhcpFormat.MessageType.Offer:
                response.NextServerIPAddress = ServerAddress;
                response.AddOption(
                    DhcpIPAddressLeaseTime.Create(RebindingTime)
                    );
                goto case DhcpFormat.MessageType.Ack;

            case DhcpFormat.MessageType.Ack:
                response.YourIPAddress = HostAddress;
                assignedAddress        = HostAddress;
                FillOptions(request, response);
                break;

            case DhcpFormat.MessageType.Nak:
                // Nothing to do
                break;

            default:
                return;
            }
            SendResponsePacket(response);
        }
示例#3
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);
        }
示例#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 override void ReceiveEvent(DhcpFormat !dhcp)
        {
            // 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 offer
            SortedList     offeredOptions = dhcp.GetOptions();
            DhcpByteOption messageType
                = offeredOptions[DhcpMessageType.OptionCode] as DhcpByteOption;

            if (messageType == null ||
                messageType.Value != (byte)DhcpFormat.MessageType.Offer)
            {
                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 DhcpClientStateRequesting(client,
                                                             serverAddress,
                                                             offeredAddress,
                                                             offeredOptions));
        }
        private void FillOptions(DhcpFormat request, DhcpFormat response)
        {
            SortedList requestOptions = request.GetOptions();

            response.AddOption(DhcpServerID.Create(ServerAddress));
            response.AddOption(DhcpRenewalTime.Create(RenewalTime));
            response.AddOption(DhcpRebindingTime.Create(RebindingTime));

            foreach (IDhcpOption option in requestOptions.Values)
            {
                byte optionCode = option.OptionCode;
                Console.WriteLine("({0}) {1}",
                                  optionCode,
                                  DhcpOptionParser.GetOptionName(optionCode));
            }

            DhcpMultiByteOption parameters =
                requestOptions[DhcpParameterRequest.OptionCode]
                as DhcpMultiByteOption;

            if (parameters == null)
            {
                return;
            }

            foreach (byte parameter in parameters.Values)
            {
                switch (parameter)
                {
                case DhcpSubnetMask.OptionCode:
                    response.AddOption(DhcpSubnetMask.Create(NetMask));
                    break;

                case DhcpDomainName.OptionCode:
                    response.AddOption(
                        DhcpDomainName.Create(DomainName.ToCharArray())
                        );
                    break;

                case DhcpRouter.OptionCode:
                    response.AddOption(DhcpRouter.Create(Routers));
                    break;

                case DhcpDomainNameServer.OptionCode:
                    response.AddOption(
                        DhcpDomainNameServer.Create(DnsServers)
                        );
                    break;
                }
            }
        }
        private void SendResponsePacket(DhcpFormat dhcp)
        {
            int packetSize = dhcp.Size + UdpFormat.Size +
                             IPFormat.Size + EthernetFormat.Size;

            byte [] packet = new byte [packetSize];

            // Write out DHCP packet
            int dhcpSize   = dhcp.Size;
            int dhcpOffset = packet.Length - dhcpSize;

            dhcp.Write(packet, dhcpOffset);

            // Create UDP Header
            UdpFormat.UdpHeader udpHeader = new UdpFormat.UdpHeader();
            udpHeader.srcPort = DhcpFormat.ServerPort;
            udpHeader.dstPort = DhcpFormat.ClientPort;
            udpHeader.length  = (ushort)(UdpFormat.Size + dhcpSize);

            // Create IP Header
            IPFormat.IPHeader ipHeader = new NetStack.Protocols.IPFormat.IPHeader();
            ipHeader.SetDefaults(IPFormat.Protocol.UDP);
            IPFormat.SetDontFragBit(ipHeader);

            ipHeader.Source      = ServerAddress;
            ipHeader.Destination = IPv4.Broadcast;
            ipHeader.totalLength = (ushort)(IPFormat.Size + UdpFormat.Size + dhcpSize);

            // Write out IP and Header
            int udpOffset = packet.Length - dhcp.Size - UdpFormat.Size;
            int ipOffset  = udpOffset - IPFormat.Size;

            UdpFormat.WriteUdpPacket(packet, ipOffset,
                                     ref ipHeader, ref udpHeader,
                                     packet, dhcpOffset, dhcpSize);

            // Add Ethernet Header
            EthernetFormat.Write(packet, 0, ServerMac,
                                 EthernetAddress.Broadcast,
                                 EthernetFormat.Protocol.IP);

            NetPacket np = new NetPacket(packet);

            if (adapter.ReceivePacket(np) == false)
            {
                Console.WriteLine("Failed to send packet");
                SetState(ServerState.Failed);
            }
        }
示例#8
0
        internal bool Send(EthernetAddress dstAddr, DhcpFormat !dhcp)
        {
            int packetSize = dhcp.Size + UdpFormat.Size +
                             IPFormat.Size + EthernetFormat.Size;

            byte [] packet = new byte [packetSize];

            // Write out DHCP packet
            int dhcpSize   = dhcp.Size;
            int dhcpOffset = packet.Length - dhcpSize;

            dhcp.Write(packet, dhcpOffset);

            // Create UDP Header
            UdpFormat.UdpHeader udpHeader = new UdpFormat.UdpHeader();
            udpHeader.srcPort = DhcpFormat.ClientPort;
            udpHeader.dstPort = DhcpFormat.ServerPort;
            udpHeader.length  = (ushort)(UdpFormat.Size + dhcpSize);

            // Create IP Header
            IPFormat.IPHeader ipHeader = new NetStack.Protocols.IPFormat.IPHeader();
            ipHeader.SetDefaults(IPFormat.Protocol.UDP);
            IPFormat.SetDontFragBit(ipHeader);

            ipHeader.Source      = IPv4.Any;
            ipHeader.Destination = IPv4.Broadcast;
            ipHeader.totalLength = (ushort)(IPFormat.Size + UdpFormat.Size + dhcpSize);

            // Write out IP and Header
            int udpOffset = packet.Length - dhcp.Size - UdpFormat.Size;
            int ipOffset  = udpOffset - IPFormat.Size;

            UdpFormat.WriteUdpPacket(packet, ipOffset,
                                     ipHeader, ref udpHeader,
                                     packet, dhcpOffset, dhcpSize);

            // Add Ethernet Header
            EthernetFormat.Write(packet, 0, adapter.HardwareAddress,
                                 dstAddr, EthernetFormat.PROTOCOL_IP);

            NetPacket np = new NetPacket(packet);

            return(udpSession.WritePacket(np));
        }
        public void Receive(NetPacket packet)
        {
            packet.Reset();

            Console.WriteLine("Received {0} bytes", packet.Length);
            if (ValidHeaders(packet) == false)
            {
                SetState(ServerState.Failed);
                return;
            }

            try {
                DhcpFormat dhcp    = DhcpFormat.Parse(packet);
                SortedList options = dhcp.GetOptions();

                DhcpByteOption message = options[DhcpMessageType.OptionCode]
                                         as DhcpByteOption;
                if (message == null)
                {
                    Console.WriteLine("MessageType option not found");
                    SetState(ServerState.Failed);
                    return;
                }

                DhcpFormat.MessageType messageType =
                    (DhcpFormat.MessageType)message.Value;

                if (DhcpFormat.IsRequestMessage(messageType) == false)
                {
                    Console.WriteLine("Inappropriate message type: {0}",
                                      message.Value);
                    SetState(ServerState.Failed);
                    return;
                }

                DhcpFormat.MessageType expected = expectActions[expectIndex, 0];
                DhcpFormat.MessageType action   = expectActions[expectIndex, 1];
                expectIndex++;

                if (messageType != expected)
                {
                    Console.WriteLine("Unexpected message type: {0} != {1}",
                                      messageType, expected);
                    SetState(ServerState.Failed);
                    return;
                }

                if (DhcpFormat.IsResponseMessage(action))
                {
                    Respond(dhcp, action);
                }

                if (expectIndex == expectActions.Length / expectActions.Rank)
                {
                    SetState(ServerState.Finished);
                }
            }
            catch (Exception e) {
                Console.WriteLine("Bad Dhcp packet: {0}", e);
                SetState(ServerState.Failed);
            }
        }
示例#10
0
 /// <summary>
 /// State should process that has arrived.
 /// </summary>
 internal virtual void ReceiveEvent(DhcpFormat !df)
 {
     DhcpClient.DebugPrint("FSM Ignored DHCP packet: {0}\n", stateName);
 }
示例#11
0
 internal override void ReceiveEvent(DhcpFormat !dhcp)
 {
 }
示例#12
0
        private void WorkerMain()
        {
            DebugPrint("Worker starting\n");

            Random r = new Random();

            transactionID = (uint)r.Next();

            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 {
                    byte [] data = udpSession.PollCopyData(PollInterval);
                    if (data != null)
                    {
                        SimpleBuffer sb   = new SimpleBuffer(data);
                        DhcpFormat   dhcp = DhcpFormat.Parse(sb);

                        // 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;
                }
            }
        }