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); }
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)); }
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)); }
private static void TakeOption(SortedList offeredOptions, byte optionCode, DhcpFormat dhcpFormat) { IDhcpOption option = offeredOptions[optionCode] as IDhcpOption; if (option != null) { dhcpFormat.AddOption(option); } }
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); }
/// <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)); }
internal override void ReceiveEvent(DhcpFormat dhcp) { //DebugStub.WriteLine("FSM DHCP packet REBINDING.\n"); }
internal override void ReceiveEvent(DhcpFormat dhcp) { //DebugStub.WriteLine("FSM DHCP packet BOUND.\n"); // ignore }
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)); }
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; } } }
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); }