private static IPv4Packet BuildDhcpRebindMessage(DhcpOffer offer, NetworkInterface inter, ushort packetId, uint dhcpTransactionId) { var hardwareAddress = new HardwareAddress(HardwareAddressType.Ethernet, inter.GetPhysicalAddress().GetAddressBytes()); var dhcpPacket = new DhcpPacket(); dhcpPacket.Operation = DhcpOperation.Request; dhcpPacket.MessageType = DhcpMessageType.Request; dhcpPacket.TransactionId = dhcpTransactionId; dhcpPacket.HardwareAddress = hardwareAddress; dhcpPacket.ClientAddress = offer.ClientAddress; dhcpPacket.Options.Add(new DhcpClientIdentifier(hardwareAddress)); var dhcpUdpPacket = new UdpPacket(); dhcpUdpPacket.SourcePort = 68; dhcpUdpPacket.DestinationPort = 67; dhcpUdpPacket.Payload = dhcpPacket; var dhcpIpPacket = new IPv4Packet(); dhcpIpPacket.Source = offer.ClientAddress; dhcpIpPacket.Destination = offer.DhcpServer; dhcpIpPacket.Identifiation = packetId; dhcpIpPacket.Payload = dhcpUdpPacket; return(dhcpIpPacket); }
static void Main(string[] args) { var interfaces = NetworkInterface.GetAllNetworkInterfaces(); foreach (var item in interfaces.Select((i, idx) => new { nr = idx + 1, inter = i })) { Console.WriteLine($"-{item.nr}- {item.inter.Name}"); } Console.Write("> Choose a interface: "); int selection = int.Parse(Console.ReadLine()); var mainInterface = interfaces[selection - 1]; var random = new Random(); ushort packetId = (ushort)random.Next(); uint dhcpTransactionId = (uint)random.Next(); ITransportPacketFactory transportPacketFactory = new TransportPacketFactoryImpl(); IApplicationPacketFactory applicationPacketFactory = new ApplicationPacketFactoryImpl(); var dhcpDiscover = BuildDhcpDiscoverMessage(mainInterface, packetId, dhcpTransactionId); bool running = true; bool rcvAck = false; ManualResetEvent rcvAckEvent = new ManualResetEvent(false); DhcpOffer selectedOffer = null; var socket = SetupPromiscousSocket(mainInterface); Console.WriteLine("Send DHCP Discover..."); dhcpDiscover.Send(socket); ISet <DhcpOffer> offers = new HashSet <DhcpOffer>(); var recieverThread = new Thread(() => { while (running) { IPv4Packet rcvPacket = IPv4Packet.Recieve(socket, transportPacketFactory, applicationPacketFactory); if (rcvPacket != null && rcvPacket.Payload is UdpPacket udpPacket) { if (udpPacket.Payload is DhcpPacket responseDhcpPacket) { switch (responseDhcpPacket.MessageType) { case DhcpMessageType.Offer: DhcpOffer offer = DhcpOffer.FromDhcpPacket(responseDhcpPacket); offers.Remove(offer); // remove old offer from server if necassary offers.Add(offer); Console.WriteLine($"New Offer from {rcvPacket.Source}"); break; case DhcpMessageType.Ack: if (!rcvAck) { Console.WriteLine("OK from server - ready to launch!"); int exitCodeInter = ExecuteNetshCommand( $"interface ipv4 set address name=\"{mainInterface.Name}\" static" + $" {selectedOffer.ClientAddress} {selectedOffer.SubnetMask} {selectedOffer.Gateway} 1" ); Console.WriteLine($"netsh Interface exit code - {exitCodeInter}"); int exitCodeDns = ExecuteNetshCommand( $"interface ipv4 set dnsservers \"{mainInterface.Name}\" static {selectedOffer.DnsServer} primary no" ); Console.WriteLine($"netsh DNS exit code - {exitCodeDns}"); rcvAckEvent.Set(); } rcvAck = true; break; } } } } }); recieverThread.Start(); Thread.Sleep(500); if (offers.Count == 0) { Console.WriteLine("Resending DHCP Discover..."); dhcpDiscover.Send(socket); } Console.WriteLine("> Press any key to stop adding new offers\n"); Console.ReadKey(); Console.WriteLine(); Console.WriteLine("-- Select DHCP server offer --"); DhcpOffer[] finalOffers = offers.ToArray(); foreach (var item in finalOffers.Select((o, idx) => new { nr = idx + 1, offer = o })) { Console.WriteLine($"-{item.nr}- Offer from {item.offer.DhcpServer}"); Console.WriteLine($" Client address: {item.offer.ClientAddress}"); Console.WriteLine($" Gateway address: {item.offer.Gateway}"); Console.WriteLine($" DNS server: {item.offer.DnsServer}"); Console.WriteLine($" Domain: {item.offer.Domain}"); } Console.Write("> Choose a offer: "); selection = int.Parse(Console.ReadLine()); selectedOffer = finalOffers[selection - 1]; Console.WriteLine("Send DHCP Request"); IPv4Packet dhcpRequest = BuildDhcpRequestMessage(selectedOffer, mainInterface, ++packetId, dhcpTransactionId); dhcpRequest.Send(socket); Console.WriteLine("Waiting for DHCP Ack and netsh..."); rcvAckEvent.WaitOne(); running = false; socket.Close(); Console.WriteLine("> Press any key to close"); Console.ReadKey(); }
protected bool Equals(DhcpOffer other) { return(Equals(DhcpServer, other.DhcpServer)); }