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); }
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); }
private static void TakeOption(SortedList !offeredOptions, byte optionCode, DhcpFormat !dhcpFormat) { IDhcpOption option = offeredOptions[optionCode] as IDhcpOption; if (option != null) { dhcpFormat.AddOption(option); } }
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); } }
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); } }
/// <summary> /// State should process that has arrived. /// </summary> internal virtual void ReceiveEvent(DhcpFormat !df) { DhcpClient.DebugPrint("FSM Ignored DHCP packet: {0}\n", stateName); }
internal override void ReceiveEvent(DhcpFormat !dhcp) { }
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; } } }