/// <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> /// <param name="otherForceOptions">Force reply options (will be sent anyway)</param> public void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData, Dictionary <DHCPOption, byte[]> otherForceOptions) { var replyBuffer = requestData; replyBuffer.op = 2; // Reply replyBuffer.yiaddr = ip.GetAddressBytes(); // Client's IP replyBuffer.options = CreateOptionStruct(msgType, replyData, otherForceOptions); // Options if (!string.IsNullOrEmpty(dhcpServer.ServerName)) { var serverNameBytes = Encoding.ASCII.GetBytes(dhcpServer.ServerName); int len = (serverNameBytes.Length > 63) ? 63 : serverNameBytes.Length; Array.Copy(serverNameBytes, replyBuffer.sname, len); replyBuffer.sname[len] = 0; } lock (requestSocket) { IPEndPoint endPoint; if ((replyBuffer.giaddr[0] == 0) && (replyBuffer.giaddr[1] == 0) && (replyBuffer.giaddr[2] == 0) && (replyBuffer.giaddr[3] == 0)) { requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); endPoint = new IPEndPoint(IPAddress.Broadcast, PORT_TO_SEND_TO_CLIENT); } else { requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false); endPoint = new IPEndPoint(new IPAddress(replyBuffer.giaddr), PORT_TO_SEND_TO_RELAY); } var DataToSend = BuildDataStructure(replyBuffer); requestSocket.SendTo(DataToSend, endPoint); } }
private byte[] CreateOptionStruct(DHCPMsgType msgType, DHCPReplyOptions replyOptions) { byte[] resultOptions = null; // Option82? var relayInfo = OptionData.GetOptionData(DHCPOption.RelayInfo, _dhcpRequest.requestData); CreateOptionElement(ref resultOptions, DHCPOption.DHCPMessageTYPE, new [] { (byte)msgType }); // Server identifier - our IP address if (_dhcpRequest.dhcpServer.ServerIdentifier != null) { CreateOptionElement(ref resultOptions, DHCPOption.ServerIdentifier, _dhcpRequest.dhcpServer.ServerIdentifier.GetAddressBytes()); } // Requested options if (replyOptions != null) { foreach (var option in replyOptions.OtherOptions.Keys) { CreateOptionElement(ref resultOptions, option, replyOptions.OtherOptions[option]); } } // 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); }
/// <summary> /// Sends DHCP reply /// </summary> /// <param name="msgType">Type of DHCP message to send</param> /// <param name="replyData">Reply options (will be sent if requested)</param> /// <param name="replyPort">Port to send on</param> public void Send(DHCPMsgType msgType, DHCPReplyOptions replyData, int replyPort) { var replyBuffer = _dhcpRequest.requestData; replyBuffer.op = 2; // Reply replyBuffer.options = CreateOptionStruct(msgType, replyData); // Options if (!string.IsNullOrEmpty(_dhcpRequest.dhcpServer.ServerName)) { var serverNameBytes = Encoding.ASCII.GetBytes(_dhcpRequest.dhcpServer.ServerName); int len = (serverNameBytes.Length > 63) ? 63 : serverNameBytes.Length; Array.Copy(serverNameBytes, replyBuffer.sname, len); replyBuffer.sname[len] = 0; } if (replyData.NextServer != null) { var nextServerBytes = replyData.NextServer.GetAddressBytes(); Array.Copy(nextServerBytes, replyBuffer.siaddr, 4); } if (replyData.BootFileName != null) { var bootFileNameBytes = Encoding.ASCII.GetBytes(replyData.BootFileName); int len = (bootFileNameBytes.Length > 127) ? 127 : bootFileNameBytes.Length; Array.Copy(bootFileNameBytes, replyBuffer.file, len); replyBuffer.file[len] = 0; } lock (_dhcpRequest.requestSocket) { IPEndPoint endPoint; if (msgType == DHCPMsgType.DHCPACK) { //Trace.WriteLine("Sending Acknowledgement to " + new IPAddress(replyBuffer.ciaddr) + ":" + replyPort); _dhcpRequest.requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false); endPoint = new IPEndPoint(new IPAddress(replyBuffer.ciaddr), replyPort); } else { if ((replyBuffer.giaddr[0] == 0) && (replyBuffer.giaddr[1] == 0) && (replyBuffer.giaddr[2] == 0) && (replyBuffer.giaddr[3] == 0)) { //Trace.WriteLine("Sending Offer To " + IPAddress.Broadcast + ":" + PORT_TO_SEND_TO_CLIENT); _dhcpRequest.requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); endPoint = new IPEndPoint(IPAddress.Broadcast, PORT_TO_SEND_TO_CLIENT); } else { //Trace.WriteLine("Sending Offer To " + new IPAddress(replyBuffer.giaddr) + ":" + PORT_TO_SEND_TO_RELAY); _dhcpRequest.requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false); endPoint = new IPEndPoint(new IPAddress(replyBuffer.giaddr), PORT_TO_SEND_TO_RELAY); } } var DataToSend = BuildDataStructure(replyBuffer); _dhcpRequest.requestSocket.SendTo(DataToSend, endPoint); } }
/// <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> /// <param name="otherForceOptions">Force reply options (will be sent anyway)</param> private void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData, Dictionary <DHCPOption, byte[]> otherForceOptions, IEnumerable <DHCPOption> forceOptions) { var replyBuffer = requestData; replyBuffer.op = 2; // Reply if (msgType == DHCPMsgType.DHCPOFFER || msgType == DHCPMsgType.DHCPACK) { replyBuffer.yiaddr = ip.GetAddressBytes(); // Client's IP if (replyData.ServerIpAddress != null) { replyBuffer.siaddr = replyData.ServerIpAddress.GetAddressBytes(); } } //IPAddress localIp = ((IPEndPoint)udp.Client.LocalEndPoint).Address; //replyData.ServerIdentifier = localIp; replyBuffer.options = CreateOptionStruct(msgType, replyData, otherForceOptions, forceOptions); // Options if (!string.IsNullOrEmpty(dhcpServer.ServerName)) { var serverNameBytes = Encoding.ASCII.GetBytes(dhcpServer.ServerName); int len = (serverNameBytes.Length > 63) ? 63 : serverNameBytes.Length; Array.Copy(serverNameBytes, replyBuffer.sname, len); replyBuffer.sname[len] = 0; } //lock (requestSocket) lock (udp) { var DataToSend = BuildDataStructure(replyBuffer); if (DataToSend.Length < 300) { var sendArray = new byte[300]; Array.Copy(DataToSend, 0, sendArray, 0, DataToSend.Length); DataToSend = sendArray; } if (dhcpServer.SendDhcpAnswerNetworkInterface != null) { udp.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, (int)IPAddress.HostToNetworkOrder(dhcpServer.SendDhcpAnswerNetworkInterface.GetIPProperties().GetIPv4Properties().Index)); } IPEndPoint endPoint = null; if ((replyBuffer.giaddr[0] == 0) && (replyBuffer.giaddr[1] == 0) && (replyBuffer.giaddr[2] == 0) && (replyBuffer.giaddr[3] == 0)) { endPoint = new IPEndPoint(dhcpServer.BroadcastAddress, PORT_TO_SEND_TO_CLIENT); udp.EnableBroadcast = true; udp.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); } else { endPoint = new IPEndPoint(new IPAddress(replyBuffer.giaddr), PORT_TO_SEND_TO_RELAY); udp.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false); } udp.Send(DataToSend, DataToSend.Length, endPoint); } }
static void discoverHandler(DHCPRequest dhcpRequest) { DHCPMsgType type = dhcpRequest.GetMsgType(); String mac = Util.bytesToMac(dhcpRequest.GetChaddr()); IPAddress ip = pool.offerIP(mac, dhcpRequest.GetRequestedIP()); DHCPReplyOptions options = defaultOptions.clone(); options.ServerIdentifier = localAddress; dhcpRequest.SendDHCPReply(DHCPMsgType.DHCPOFFER, ip, defaultOptions); sendNotify(DhcpNotify.NotifyType.DISCOVER, String.Format("RTDhcpServer receives DHCP discover message from {0}, offer {1}", mac, ip)); }
/// <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> /// <param name="otherForceOptions">Force reply options (will be sent anyway)</param> private void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData, Dictionary <DHCPOption, byte[]> otherForceOptions, IEnumerable <DHCPOption> forceOptions) { var replyBuffer = requestData; replyBuffer.op = 2; // Reply replyBuffer.yiaddr = ip.GetAddressBytes(); // Client's IP if (replyData.ServerIpAddress != null) { replyBuffer.siaddr = replyData.ServerIpAddress.GetAddressBytes(); } replyBuffer.options = CreateOptionStruct(msgType, replyData, otherForceOptions, forceOptions); // Options if (!string.IsNullOrEmpty(dhcpServer.ServerName)) { var serverNameBytes = Encoding.ASCII.GetBytes(dhcpServer.ServerName); int len = (serverNameBytes.Length > 63) ? 63 : serverNameBytes.Length; Array.Copy(serverNameBytes, replyBuffer.sname, len); replyBuffer.sname[len] = 0; } lock (requestSocket) { var DataToSend = BuildDataStructure(replyBuffer); if (DataToSend.Length < 300) { var sendArray = new byte[300]; Array.Copy(DataToSend, 0, sendArray, 0, DataToSend.Length); DataToSend = sendArray; } IPEndPoint endPoint; if ((replyBuffer.giaddr[0] == 0) && (replyBuffer.giaddr[1] == 0) && (replyBuffer.giaddr[2] == 0) && (replyBuffer.giaddr[3] == 0)) { //requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); //endPoint = new IPEndPoint(dhcpServer.BroadcastAddress, PORT_TO_SEND_TO_CLIENT); var udp = new UdpClient(); udp.EnableBroadcast = true; udp.Send(DataToSend, DataToSend.Length, new IPEndPoint(dhcpServer.BroadcastAddress, 68)); udp.Close(); } else { requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false); endPoint = new IPEndPoint(new IPAddress(replyBuffer.giaddr), PORT_TO_SEND_TO_RELAY); requestSocket.SendTo(DataToSend, endPoint); } } }
public DHCPClient(Guid guid, string mac, SocketType type, IPEndPoint endpoint) { this.type = type; this.endp = endpoint; this.wdsclient = false; this.pollInterval = Convert.ToInt16(Settings.PollInterval); this.retrycount = Convert.ToInt16(Settings.RetryCount); this.actionDone = false; this.guid = guid; this.mac = mac; this.id = string.Format("{0}-{1}", this.guid, this.mac); this.adminMessage = "Client ID: {0}".F(this.id); this.nextAction = NextActionOptionValues.Approval; this.msgType = DHCPMsgType.Offer; this.arch = Architecture.Intelx86PC; this.bootfile = string.Empty; this.undi_major = 2; this.undi_minor = 1; }
//mac announced itself, established IP etc.... //send the offer to the mac public void SendDHCPMessage(DHCPMsgType msgType, cDHCPStruct ddHcpS) { byte[] Subn, HostID, DataToSend; //we shall leave everything as is structure wise //shall CHANGE the type to OFFER //shall set the client's IP-Address try { //change message type to reply ddHcpS.dStruct.D_op = 2; //reply //subnet Subn = IPAddress.Parse(ddHcpS.dData.SubMask).GetAddressBytes(); //create your ip address ddHcpS.dStruct.D_yiaddr = IPAddress.Parse(ddHcpS.dData.IPAddr).GetAddressBytes(); //Host ID HostID = System.Text.Encoding.ASCII.GetBytes(ddHcpS.dData.ServerName); CreateOptionStruct(ref ddHcpS, msgType); //send the data to the unit DataToSend = BuildDataStructure(ddHcpS.dStruct); cUdp.SendData(DataToSend); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { Subn = null; //LeaseTime= null; HostID = null; DataToSend = null; } }
private void CreateOptionStruct(ref cDHCPStruct ddHcps, DHCPMsgType OptionReplyMsg) { byte[] PReqList, t1, LeaseTime, MyIp; try { //we look for the parameter request list PReqList = GetOptionData(DHCPOptionEnum.ParameterRequestList, ddHcps); //erase the options array, and set the message type to ack ddHcps.dStruct.D_options = null; CreateOptionElement(DHCPOptionEnum.DHCPMessageTYPE, new byte[] { (byte)OptionReplyMsg }, ref ddHcps.dStruct.D_options); //server identifier, my IP MyIp = IPAddress.Parse(ddHcps.dData.MyIP).GetAddressBytes(); CreateOptionElement(DHCPOptionEnum.ServerIdentifier, MyIp, ref ddHcps.dStruct.D_options); //PReqList contains the option data in a byte that is requested by the unit foreach (byte i in PReqList) { t1 = null; switch ((DHCPOptionEnum)i) { case DHCPOptionEnum.SubnetMask: t1 = IPAddress.Parse(ddHcps.dData.SubMask).GetAddressBytes(); break; case DHCPOptionEnum.Router: t1 = IPAddress.Parse(ddHcps.dData.RouterIP).GetAddressBytes(); break; case DHCPOptionEnum.DomainNameServer: t1 = IPAddress.Parse(ddHcps.dData.DomainIP).GetAddressBytes(); break; case DHCPOptionEnum.DomainName: t1 = System.Text.Encoding.ASCII.GetBytes(ddHcps.dData.ServerName); break; case DHCPOptionEnum.ServerIdentifier: t1 = IPAddress.Parse(ddHcps.dData.MyIP).GetAddressBytes(); break; case DHCPOptionEnum.LogServer: t1 = System.Text.Encoding.ASCII.GetBytes(ddHcps.dData.LogServerIP); break; case DHCPOptionEnum.NetBIOSoverTCPIPNameServer: break; } if (t1 != null) { CreateOptionElement((DHCPOptionEnum)i, t1, ref ddHcps.dStruct.D_options); } } //lease time LeaseTime = new byte[4]; LeaseTime[3] = (byte)(ddHcps.dData.LeaseTime); LeaseTime[2] = (byte)(ddHcps.dData.LeaseTime >> 8); LeaseTime[1] = (byte)(ddHcps.dData.LeaseTime >> 16); LeaseTime[0] = (byte)(ddHcps.dData.LeaseTime >> 24); CreateOptionElement(DHCPOptionEnum.IPAddressLeaseTime, LeaseTime, ref ddHcps.dStruct.D_options); CreateOptionElement(DHCPOptionEnum.RenewalTimeValue_T1, LeaseTime, ref ddHcps.dStruct.D_options); CreateOptionElement(DHCPOptionEnum.RebindingTimeValue_T2, LeaseTime, ref ddHcps.dStruct.D_options); //create the end option Array.Resize(ref ddHcps.dStruct.D_options, ddHcps.dStruct.D_options.Length + 1); Array.Copy(new byte[] { 255 }, 0, ddHcps.dStruct.D_options, ddHcps.dStruct.D_options.Length - 1, 1); //send the data to the unit } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { LeaseTime = null; PReqList = null; t1 = 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; }
/// <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); }
/// <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> /// <param name="forceOptions">Force reply options (will be sent anyway)</param> public void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData, IEnumerable <DHCPOption> forceOptions) { SendDHCPReply(msgType, ip, replyData, null, forceOptions); }
/// <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> /// <param name="otherForceOptions">Force reply options (will be sent anyway)</param> public void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData, Dictionary <DHCPOption, byte[]> otherForceOptions) { SendDHCPReply(msgType, ip, replyData, otherForceOptions, null); }
/// <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, null); }
private byte[] CreateOptionStruct(DHCPMsgType msgType, DHCPReplyOptions replyOptions, Dictionary <DHCPOption, byte[]> otherForceOptions, IEnumerable <DHCPOption> forceOptions) { Dictionary <DHCPOption, byte[]> options = new Dictionary <DHCPOption, byte[]>(); 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)) { options[DHCPOption.ServerIdentifier] = replyOptions.ServerIdentifier.GetAddressBytes(); } if (reqList == null && forceOptions != null) { reqList = new DHCPOption[0]; } // Requested options if ((reqList != null) && (replyOptions != null)) { foreach (DHCPOption i in reqList.Union(forceOptions).Distinct().OrderBy(x => (int)x)) { 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) { options[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); options[DHCPOption.IPAddressLeaseTime] = leaseTime; if (replyOptions.RenewalTimeValue_T1.HasValue) { 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); options[DHCPOption.RenewalTimeValue_T1] = leaseTime; } if (replyOptions.RebindingTimeValue_T2.HasValue) { 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); options[DHCPOption.RebindingTimeValue_T2] = leaseTime; } } } // Other requested options if (otherForceOptions != null) { foreach (var option in otherForceOptions.Keys) { options[option] = otherForceOptions[option]; if (option == DHCPOption.RelayInfo) { relayInfo = null; } } } // Option 82? Send it back! if (relayInfo != null) { options[DHCPOption.RelayInfo] = relayInfo; } foreach (var option in options.OrderBy(x => (int)x.Key)) { CreateOptionElement(ref resultOptions, option.Key, option.Value); } // Create the end option Array.Resize(ref resultOptions, resultOptions.Length + 1); Array.Copy(new byte[] { 255 }, 0, resultOptions, resultOptions.Length - 1, 1); return(resultOptions); }
/// <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> /// <param name="otherForceOptions">Force reply options (will be sent anyway)</param> public void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData, Dictionary<DHCPOption, byte[]> otherForceOptions) { var replyBuffer = requestData; replyBuffer.op = 2; // Reply replyBuffer.yiaddr = ip.GetAddressBytes(); // Client's IP replyBuffer.options = CreateOptionStruct(msgType, replyData, otherForceOptions); // Options if (!string.IsNullOrEmpty(dhcpServer.ServerName)) { var serverNameBytes = Encoding.ASCII.GetBytes(dhcpServer.ServerName); int len = (serverNameBytes.Length > 63) ? 63 : serverNameBytes.Length; Array.Copy(serverNameBytes, replyBuffer.sname, len); replyBuffer.sname[len] = 0; } lock (requestSocket) { IPEndPoint endPoint; if ((replyBuffer.giaddr[0] == 0) && (replyBuffer.giaddr[1] == 0) && (replyBuffer.giaddr[2] == 0) && (replyBuffer.giaddr[3] == 0)) { requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); endPoint = new IPEndPoint(IPAddress.Broadcast, PORT_TO_SEND_TO_CLIENT); } else { requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false); endPoint = new IPEndPoint(new IPAddress(replyBuffer.giaddr), PORT_TO_SEND_TO_RELAY); } var DataToSend = BuildDataStructure(replyBuffer); requestSocket.SendTo(DataToSend, endPoint); } }
/// <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> /// <param name="otherForceOptions">Force reply options (will be sent anyway)</param> private async void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData, Dictionary <DHCPOption, byte[]> otherForceOptions, IEnumerable <DHCPOption> forceOptions) { var replyBuffer = requestData; replyBuffer.op = 2; // Reply replyBuffer.yiaddr = ip.GetAddressBytes(); // Client's IP if (replyData.ServerIpAddress != null) { replyBuffer.siaddr = replyData.ServerIpAddress.GetAddressBytes(); } replyBuffer.options = CreateOptionStruct(msgType, replyData, otherForceOptions, forceOptions); // Options if (!string.IsNullOrEmpty(dhcpServer.ServerName)) { var serverNameBytes = Encoding.ASCII.GetBytes(dhcpServer.ServerName); int len = (serverNameBytes.Length > 63) ? 63 : serverNameBytes.Length; Array.Copy(serverNameBytes, replyBuffer.sname, len); replyBuffer.sname[len] = 0; } //lock (requestSocket) { var DataToSend = BuildDataStructure(replyBuffer); if (DataToSend.Length < 300) { var sendArray = new byte[300]; Array.Copy(DataToSend, 0, sendArray, 0, DataToSend.Length); DataToSend = sendArray; } if ((replyBuffer.giaddr[0] == 0) && (replyBuffer.giaddr[1] == 0) && (replyBuffer.giaddr[2] == 0) && (replyBuffer.giaddr[3] == 0)) { //requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); //endPoint = new IPEndPoint(dhcpServer.BroadcastAddress, PORT_TO_SEND_TO_CLIENT); //var udp = new UdpClient(); //udp.EnableBroadcast = true; //udp.Send(DataToSend, DataToSend.Length, new IPEndPoint(dhcpServer.BroadcastAddress, 68)); //udp.Close(); var datagramsocket = new Windows.Networking.Sockets.DatagramSocket(); using (var stream = await datagramsocket.GetOutputStreamAsync(new Windows.Networking.HostName(dhcpServer.BroadcastAddress), PORT_TO_SEND_TO_CLIENT.ToString())) { using (var datawriter = new Windows.Storage.Streams.DataWriter(stream)) { datawriter.WriteBytes(DataToSend); await datawriter.StoreAsync(); } } } else { //requestSocket .SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false); //endPoint = new IPEndPoint(new IPAddress(replyBuffer.giaddr), PORT_TO_SEND_TO_RELAY); //requestSocket.SendTo(DataToSend, endPoint); using (var stream = await requestSocket.GetOutputStreamAsync(new Windows.Networking.HostName(new IPAddress(replyBuffer.giaddr).ToString()), PORT_TO_SEND_TO_RELAY.ToString())) { using (var datawriter = new Windows.Storage.Streams.DataWriter(stream)) { datawriter.WriteBytes(DataToSend); await datawriter.StoreAsync(); } } } } }