/// <summary> /// Sends DHCP reply /// </summary> /// <param name="msgType">Type of DHCP message to send</param> /// <param name="ip">IP for client</param> /// <param name="replyData">Reply options (will be sent if requested)</param> public void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData) { SendDHCPReply(msgType, ip, replyData, null); }
private byte[] CreateOptionStruct(DHCPMsgType msgType, DHCPReplyOptions replyOptions, Dictionary <DHCPOption, byte[]> otherForceOptions) { byte[] resultOptions = null; // Requested options var reqList = GetRequestedOptionsList(); // Option82? var relayInfo = this.GetOptionData(DHCPOption.RelayInfo); CreateOptionElement(ref resultOptions, DHCPOption.DHCPMessageTYPE, new byte[] { (byte)msgType }); // Server identifier - our IP address if ((replyOptions != null) && (replyOptions.ServerIdentifier != null)) { CreateOptionElement(ref resultOptions, DHCPOption.ServerIdentifier, replyOptions.ServerIdentifier.GetAddressBytes()); } // Requested options if ((reqList != null) && (replyOptions != null)) { foreach (DHCPOption i in reqList) { byte[] optionData = null; // If it's force option - ignore it. We'll send it later. if ((otherForceOptions != null) && (otherForceOptions.TryGetValue(i, out optionData))) { continue; } switch (i) { case DHCPOption.SubnetMask: if (replyOptions.SubnetMask != null) { optionData = replyOptions.SubnetMask.GetAddressBytes(); } break; case DHCPOption.Router: if (replyOptions.RouterIP != null) { optionData = replyOptions.RouterIP.GetAddressBytes(); } break; case DHCPOption.DomainNameServers: if (replyOptions.DomainNameServers != null) { optionData = new byte[] { }; foreach (var dns in replyOptions.DomainNameServers) { var dnsserv = dns.GetAddressBytes(); Array.Resize(ref optionData, optionData.Length + 4); Array.Copy(dnsserv, 0, optionData, optionData.Length - 4, 4); } } break; case DHCPOption.DomainName: if (!string.IsNullOrEmpty(replyOptions.DomainName)) { optionData = System.Text.Encoding.ASCII.GetBytes(replyOptions.DomainName); } break; case DHCPOption.ServerIdentifier: if (replyOptions.ServerIdentifier != null) { optionData = replyOptions.ServerIdentifier.GetAddressBytes(); } break; case DHCPOption.LogServer: if (replyOptions.LogServerIP != null) { optionData = replyOptions.LogServerIP.GetAddressBytes(); } break; case DHCPOption.StaticRoutes: case DHCPOption.StaticRoutesWin: if (replyOptions.StaticRoutes != null) { optionData = new byte[] { }; foreach (var route in replyOptions.StaticRoutes) { var routeData = route.BuildRouteData(); Array.Resize(ref optionData, optionData.Length + routeData.Length); Array.Copy(routeData, 0, optionData, optionData.Length - routeData.Length, routeData.Length); } } break; default: replyOptions.OtherRequestedOptions.TryGetValue(i, out optionData); break; } if (optionData != null) { CreateOptionElement(ref resultOptions, i, optionData); } } } if (GetMsgType() != DHCPMsgType.DHCPINFORM) { // Lease time if (replyOptions != null) { var leaseTime = new byte[4]; leaseTime[3] = (byte)(replyOptions.IPAddressLeaseTime); leaseTime[2] = (byte)(replyOptions.IPAddressLeaseTime >> 8); leaseTime[1] = (byte)(replyOptions.IPAddressLeaseTime >> 16); leaseTime[0] = (byte)(replyOptions.IPAddressLeaseTime >> 24); CreateOptionElement(ref resultOptions, DHCPOption.IPAddressLeaseTime, leaseTime); leaseTime[3] = (byte)(replyOptions.RenewalTimeValue_T1); leaseTime[2] = (byte)(replyOptions.RenewalTimeValue_T1 >> 8); leaseTime[1] = (byte)(replyOptions.RenewalTimeValue_T1 >> 16); leaseTime[0] = (byte)(replyOptions.RenewalTimeValue_T1 >> 24); CreateOptionElement(ref resultOptions, DHCPOption.RenewalTimeValue_T1, leaseTime); leaseTime[3] = (byte)(replyOptions.RebindingTimeValue_T2); leaseTime[2] = (byte)(replyOptions.RebindingTimeValue_T2 >> 8); leaseTime[1] = (byte)(replyOptions.RebindingTimeValue_T2 >> 16); leaseTime[0] = (byte)(replyOptions.RebindingTimeValue_T2 >> 24); CreateOptionElement(ref resultOptions, DHCPOption.RebindingTimeValue_T2, leaseTime); } } // Other requested options if (otherForceOptions != null) { foreach (var option in otherForceOptions.Keys) { CreateOptionElement(ref resultOptions, option, otherForceOptions[option]); if (option == DHCPOption.RelayInfo) { relayInfo = null; } } } // Option 82? Send it back! if (relayInfo != null) { CreateOptionElement(ref resultOptions, DHCPOption.RelayInfo, relayInfo); } // Create the end option Array.Resize(ref resultOptions, resultOptions.Length + 1); Array.Copy(new byte[] { 255 }, 0, resultOptions, resultOptions.Length - 1, 1); return(resultOptions); }