From 564142d81102f500d858850f8a33e592eceda06f Mon Sep 17 00:00:00 2001 From: Wizche Date: Mon, 25 Nov 2019 22:05:04 +0100 Subject: [PATCH] Initial commit --- .gitignore | 32 +++++++++++++++++ Program.cs | 95 +++++++++++++++++++++++++++++++++++++++++++++++++ dhcpshot.csproj | 13 +++++++ 3 files changed, 140 insertions(+) create mode 100644 .gitignore create mode 100644 Program.cs create mode 100644 dhcpshot.csproj diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..07ba847 --- /dev/null +++ b/.gitignore @@ -0,0 +1,32 @@ +*.swp +*.*~ +project.lock.json +.DS_Store +*.pyc + +# Visual Studio Code +.vscode + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ +msbuild.log +msbuild.err +msbuild.wrn + +# Visual Studio 2015 +.vs/ \ No newline at end of file diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..47d8495 --- /dev/null +++ b/Program.cs @@ -0,0 +1,95 @@ +using System; +using System.CommandLine; +using System.CommandLine.Invocation; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using DotNetProjects.DhcpServer; + +namespace dhcpshot +{ + class Program + { + static void Main(string[] args) + { + var rootCommand = new RootCommand + { + new Option( + new string[] { "--interface-ip", "-i" }, + "IPv4 for the interface we are going to listen to") + { + Argument = new Argument{ Arity = ArgumentArity.ExactlyOne }, + Required = true + }, + new Option( + new string[] { "--target-ip", "-t" }, + "IPv4 that will be given to the DHCP client, if none given it will be generated from interface IP") + { + Argument = new Argument() + } + }; + rootCommand.Description = "DHCPshot - Assign IP address to first client asking on the specified interface"; + rootCommand.Handler = CommandHandler.Create(StartServer); + rootCommand.InvokeAsync(args).Wait(); + } + + public static void StartServer(string interfaceIp, string targetIp) + { + Console.WriteLine($"Looking for interface for IP {interfaceIp}"); + var intf = NetworkInterface.GetAllNetworkInterfaces() + .Where( + x => x.GetIPProperties().UnicastAddresses + .Any(y => y.Address.Equals(IPAddress.Parse(interfaceIp))) + ).FirstOrDefault(); + if (intf == null) + { + Console.WriteLine($"Interface for IP {interfaceIp} not found!"); + return; + } + Console.WriteLine($"Starting DHCP server on interface {intf.Name}"); + var server = new DHCPServer(); + + if (targetIp == null) + { + var rnd = new Random(); + var ip_bytes = interfaceIp.Split("."); + var lastByte = int.Parse(ip_bytes[3]); + int newByte = rnd.Next(2, 254); + while (newByte == lastByte) + { + newByte = rnd.Next(2, 254); + } + ip_bytes[3] = newByte.ToString(); + targetIp = string.Join(".", ip_bytes); + } + Console.WriteLine($"Client will receive IP {targetIp}"); + server.OnDataReceived += delegate (DHCPRequest dhcpRequest) + { + Request(dhcpRequest, IPAddress.Parse(targetIp)); + }; + server.BroadcastAddress = IPAddress.Broadcast; + server.SendDhcpAnswerNetworkInterface = intf; + server.Start(); + Console.WriteLine("Running DHCP server... Press CTRL-C to exit"); + } + + static void Request(DHCPRequest dhcpRequest, IPAddress targetIp) + { + try + { + var type = dhcpRequest.GetMsgType(); + var replyOptions = new DHCPReplyOptions(); + replyOptions.SubnetMask = IPAddress.Parse("255.255.255.0"); + + if (type == DHCPMsgType.DHCPDISCOVER) + dhcpRequest.SendDHCPReply(DHCPMsgType.DHCPOFFER, targetIp, replyOptions); + if (type == DHCPMsgType.DHCPREQUEST) + dhcpRequest.SendDHCPReply(DHCPMsgType.DHCPACK, targetIp, replyOptions); + } + catch (Exception ex) + { + Console.WriteLine(ex); + } + } + } +} \ No newline at end of file diff --git a/dhcpshot.csproj b/dhcpshot.csproj new file mode 100644 index 0000000..7d97e7f --- /dev/null +++ b/dhcpshot.csproj @@ -0,0 +1,13 @@ + + + + Exe + netcoreapp3.0 + + + + + + + +