private void SendDhcpMessage(string dest, DhcpMessgeType msgType, DhcpData data, OwnedIpAddress newClient) { try { var dataToSend = data.BuildSendData(msgType, newClient.Ip); udpListener.SendData(dest, dataToSend); } catch (Exception e) { ErrorRaised?.Invoke(this, new ErrorMessageEventArgs { Message = e.Message }); } }
// override method for broadcast private void SendDhcpMessage(DhcpMessgeType msgType, DhcpData data, OwnedIpAddress newClient) { SendDhcpMessage(IPAddress.Broadcast.ToString(), msgType, data, newClient); }
public void UdpListener_Received(byte[] data, IPEndPoint endPoint) { try { var dhcpData = new DhcpData(data) { RelatedServer = this }; var msgType = dhcpData.GetCurrentMessageType(); var client = dhcpData.GetClientInfo(); switch (msgType) { case DhcpMessgeType.DHCP_DISCOVER: MessageRaised?.Invoke(this, new MessageEventArgs { Message = "DHCPDISCOVER received." }); Discovered?.Invoke(client); var newIp = ownedIpAddressPool.Find(x => (x.AuthorizedClientMac == client.MacAddress) || (x.IsAllocated == false && x.AuthorizedClientMac == null)); if (newIp.Ip == null) { MessageRaised?.Invoke(this, new MessageEventArgs { Message = "No ip is available to allocate." }); return; } MessageRaised?.Invoke(this, new MessageEventArgs { Message = "DHCPOFFER sent." }); // MUST be unicast over raw socket (unimplemented) // broadcast used SendDhcpMessage(DhcpMessgeType.DHCP_OFFER, dhcpData, newIp); break; case DhcpMessgeType.DHCP_REQUEST: MessageRaised?.Invoke(this, new MessageEventArgs { Message = "DHCPREQUEST received." }); Requested?.Invoke(client); switch (GetDhcpRequestType(client, endPoint)) { // respond to client which has responded to DHCPOFFER message from this server case DhcpRequestType.Selecting: MessageRaised?.Invoke(this, new MessageEventArgs { Message = "Response to DHCPREQUEST generated during SELECTING state." }); if (_settings.ServerIp.Equals(client.ServerAddress)) { var allocatedIp = ownedIpAddressPool.Find(x => x.Ip.Equals(client.RequestAddress)); if (allocatedIp.Ip != null && !allocatedIp.IsAllocated) { allocatedIp.IsAllocated = true; allocatedIp.AuthorizedClientMac = client.MacAddress; MessageRaised?.Invoke(this, new MessageEventArgs { Message = "DHCPACK sent." }); // broadcast SendDhcpMessage(DhcpMessgeType.DHCP_ACK, dhcpData, allocatedIp); } } break; case DhcpRequestType.InitReboot: MessageRaised?.Invoke(this, new MessageEventArgs { Message = "Response to DHCPREQUEST generated during INIT-REBOOT state." }); if (!client.RelayAgentAddress.Equals(IPAddress.Any)) { MessageRaised?.Invoke(this, new MessageEventArgs { Message = "Relay agent is not supported in this version." }); } var rebootIp = ownedIpAddressPool.Find(x => x.Ip.Equals(client.RequestAddress)); if (rebootIp.Ip != null && rebootIp.AuthorizedClientMac == client.MacAddress) { // broadcast SendDhcpMessage(DhcpMessgeType.DHCP_ACK, dhcpData, rebootIp); MessageRaised?.Invoke(this, new MessageEventArgs { Message = "DHCPACK sent." }); } break; case DhcpRequestType.ReNewing: MessageRaised?.Invoke(this, new MessageEventArgs { Message = "Response to DHCPREQUEST generated during RENEWING state." }); var reNewIp = ownedIpAddressPool.Find(x => x.Ip.Equals(client.ClientAddress)); if (reNewIp.Ip != null && reNewIp.AuthorizedClientMac == client.MacAddress) { // unicast SendDhcpMessage(client.ClientAddress.ToString(), DhcpMessgeType.DHCP_ACK, dhcpData, reNewIp); MessageRaised?.Invoke(this, new MessageEventArgs { Message = "DHCPACK sent." }); } break; case DhcpRequestType.ReBinding: MessageRaised?.Invoke(this, new MessageEventArgs { Message = "Response to DHCPREQUEST generated during REBINDING state." }); var reBindIp = ownedIpAddressPool.Find(x => x.IsAllocated == false); if (reBindIp.Ip != null) { reBindIp.IsAllocated = true; reBindIp.AuthorizedClientMac = client.MacAddress; // broadcast SendDhcpMessage(DhcpMessgeType.DHCP_ACK, dhcpData, reBindIp); MessageRaised?.Invoke(this, new MessageEventArgs { Message = "DHCPACK sent." }); } break; default: throw new ArgumentOutOfRangeException(); } break; case DhcpMessgeType.DHCP_DECLINE: MessageRaised?.Invoke(this, new MessageEventArgs { Message = "DHCPDECLINE received." }); var declinedIp = ownedIpAddressPool.Find(x => x.Ip.Equals(client.ClientAddress)); if (declinedIp.Ip != null) { ownedIpAddressPool.Remove(declinedIp); } break; case DhcpMessgeType.DHCP_RELEASE: MessageRaised?.Invoke(this, new MessageEventArgs { Message = "DHCPRELESE received." }); var releasedIp = ownedIpAddressPool.Find(x => x.Ip.Equals(client.ClientAddress)); if (releasedIp.Ip != null) { releasedIp.IsAllocated = false; } break; case DhcpMessgeType.DHCP_INFORM: MessageRaised?.Invoke(this, new MessageEventArgs { Message = "DHCPINFORM received." }); // unicast SendDhcpMessage(client.ClientAddress.ToString(), DhcpMessgeType.DHCP_ACK, dhcpData, null); break; default: throw new ArgumentOutOfRangeException(); } } catch (Exception e) { ErrorRaised?.Invoke(this, new ErrorMessageEventArgs { Message = e.Message }); Terminate(); throw e; } }