static void PollNow(object o) { //Debug.WriteLine("Poll Now"); if (nic != null && nic.IsLinkUp) { if (!Adapter.DhcpDisabled && AreRenewing && IPAddress != null) { DHCP.SendMessage(DHCP.Request); } else if (!Adapter.DhcpDisabled && IPAddress == null) { DHCP.SendMessage(DHCP.Discover); } if (Adapter.IPAddress != null && Adapter.Gateway != null && Adapter.GatewayMac == null) { ARP.SendARP_Probe(Adapter.Gateway); } if (IPAddress != null) { ARP.SendARP_Gratuitus(); } } }
/// <summary> /// Take care of a packet of DHCP stuff /// </summary> /// <param name="payload"></param> public static void HandlePacket(byte[] payload) { //Debug.WriteLine("Handling DHCP packet"); // Check Transaction ID! if (transactionID == null || payload[46] != transactionID[0] || payload[47] != transactionID[1] || payload[48] != transactionID[2] || payload[49] != transactionID[3]) { return; } // To determine the type, we need to find the magic cookie, then find option 0x35h // 02 == Offer, 05 == ACK, 06 = NAK var options = ParseOptions(payload); //Debug.WriteLine("DHCP PKT"); if (options.Contains("53")) { //Debug.WriteLine("Rec'd DHCP OFFER - 1"); if (((byte[])(options["53"]))[0] == 0x02) // Offer { //Debug.WriteLine("Rec'd DHCP OFFER"); ushort ipHeaderLength = (ushort)((payload[14] & 0x0f) * 4); PendingIpAddress = Utility.ExtractRangeFromArray(payload, ipHeaderLength + 38, 4); if (options.Contains("54")) { Adapter.Gateway = (byte[])options["54"]; // DHCP Server } if (options.Contains("6")) { Adapter.DomainNameServer = (byte[])options["6"]; // DNS Server } if (options.Contains("1")) { Adapter.SubnetMask = (byte[])options["1"]; // Subnet } if (options.Contains("3")) { Adapter.Gateway = (byte[])options["3"]; // Router } if (options.Contains("58")) { RenewTimer.Change((int)(((byte[])options["58"]).ToInt() * 1050), TwoHoursInMilliseconds); // Got a Renew time } if (options.Contains("51")) { RenewTimer.Change((int)(((byte[])options["51"]).ToInt() * 750), TwoHoursInMilliseconds); // Got a Lease Time (I am using 750, so we renew after 75% of lease has been consumed) } Adapter.GatewayMac = Utility.ExtractRangeFromArray(payload, 6, 6); // Initial gateway MAC. Will get confirmed/updated by an ARP Probe SendMessage(DHCP.Request); } else if (((byte[])options["53"])[0] == 0x05) // ACK or Acknowledgement { // Parse out the Gateway, DNS Servers, IP address, and apply set all the variables with it... //Debug.WriteLine("Rec'd DHCP ACK"); if (options.Contains("54")) { Adapter.Gateway = (byte[])options["54"]; // DHCP Server } if (options.Contains("6")) { Adapter.DomainNameServer = (byte[])options["6"]; // DNS Server } if (options.Contains("1")) { Adapter.SubnetMask = (byte[])options["1"]; // Subnet } if (options.Contains("3")) { Adapter.Gateway = (byte[])options["3"]; // Router } if (options.Contains("58")) { RenewTimer.Change((int)(((byte[])options["58"]).ToInt() * 1050), TwoHoursInMilliseconds); // Got a Renew time } if (options.Contains("51")) { RenewTimer.Change((int)(((byte[])options["51"]).ToInt() * 750), TwoHoursInMilliseconds); // Got a Lease Time (I am using 750, so we renew after 75% of lease has been consumed) } Adapter.GatewayMac = Utility.ExtractRangeFromArray(payload, 6, 6); // Initial gateway MAC. Will get confirmed/updated by an ARP Probe transactionID = null; Adapter.AreRenewing = false; Adapter.IPAddress = PendingIpAddress ?? Adapter.IPAddress; Adapter.startupHold.Set(); // This will release the Adapter.Start() Method! (if waiting) Debug.WriteLine("DHCP SUCCESS! We have an IP Address - " + Adapter.IPAddress.ToAddress() + "; Gateway: " + Adapter.Gateway.ToAddress()); ARP.SendARP_Probe(Adapter.Gateway); // Confirm Gateway MAC address } else if (((byte[])options["53"])[0] == 0x06) // NACK or Not Acknowledged! { Debug.WriteLine("DHCP N-ACK"); transactionID = null; Adapter.AreRenewing = false; // We have failed to get an IP address for some reason...! Adapter.IPAddress = null; Adapter.Gateway = null; Adapter.GatewayMac = null; } } }