예제 #1
0
 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
         });
     }
 }
예제 #2
0
 // override method for broadcast
 private void SendDhcpMessage(DhcpMessgeType msgType, DhcpData data, OwnedIpAddress newClient)
 {
     SendDhcpMessage(IPAddress.Broadcast.ToString(), msgType, data, newClient);
 }
예제 #3
0
        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;
            }
        }