/// <summary> /// Add DHCP header in packet /// </summary> /// <param name="packet"></param> /// <param name="xid"></param> /// <param name="clientIP"></param> /// <param name="messageType"></param> private static unsafe void addHeader(NetPacketDesc *packet, uint xid, byte[] clientIP, byte messageType) { DHCPBootstrapHeader *header = (DHCPBootstrapHeader *)(packet->buffer + packet->start); Memory.Memclear(header, sizeof(DHCPBootstrapHeader)); header->Opcode = 1; // REQUEST header->HardwareType = HARDTYPE_ETH; // Ethernet header->HardwareAddressLength = 6; // IPV4 header->Hops = 0; header->TransactionID = Byte.ReverseBytes(xid); header->SecondsElapsed = 0; // NULLLLL header->BootpFlags = 0; // NONNNN for (int i = 0; i < 4; i++) { header->ClientIP[i] = clientIP[i]; } Network.GetMac(header->ClientMac); packet->end += (short)sizeof(DHCPBootstrapHeader); /** * Default options */ byte *opt = packet->buffer + packet->end; uint *topt = (uint *)opt; *topt = Byte.ReverseBytes(MAGISCH_KOEKJE); // 4 bytes! opt += 4; // Another FOUR! /** * Set message type */ *opt++ = OPT_DHCP_MESSAGE_TYPE; // OPT_DHCP_MESSAGE_TYPE *opt++ = 1; *opt++ = messageType; packet->end += 7; }
/// <summary> /// Prints the DHCP bootstrap header /// </summary> /// <param name="header">The header</param> private static unsafe void Debug(DHCPBootstrapHeader *header) { Console.WriteLine("================================\nDHCP DEBUG\n=========================="); Console.Write("DHCP: opcode = "); Console.WriteHex(header->Opcode); Console.Write(", htype = "); Console.WriteHex(header->HardwareType); Console.Write(", hlen = "); Console.WriteHex(header->HardwareAddressLength); Console.Write(", hops = "); Console.WriteHex(header->Hops); Console.Write(", xid = "); Console.WriteHex(Byte.ReverseBytes(header->TransactionID)); Console.Write(", secs = "); Console.WriteNum(Byte.ReverseBytes(header->SecondsElapsed)); Console.Write(", flags = "); Console.WriteHex(Byte.ReverseBytes(header->BootpFlags)); Console.WriteLine(""); }
/// <summary> /// Perform a DHCP request /// </summary> /// <param name="buffer">Old packet</param> private static unsafe void request(byte *buffer, byte[] ip) { DHCPBootstrapHeader *header = (DHCPBootstrapHeader *)buffer; NetPacketDesc * packet = NetPacket.Alloc(); byte[] tmp = new byte[4]; /** * Write header to packet */ addHeader(packet, Byte.ReverseBytes(header->TransactionID), tmp, DHCP_REQUEST); /** * Write our received ip */ byte *buf = packet->buffer + packet->end; *buf++ = OPT_REQ_IP; *buf++ = 4; // IP is 4 bytes for (int i = 0; i < 4; i++) { *buf++ = header->YourClientIP[i]; } packet->end += 6; string hostname = Network.GetHostName(); int hostnameLength = hostname.Length; if (hostnameLength > 0xFF) { hostnameLength = 0xFF; } /** * Write our hostname */ buf = packet->buffer + packet->end; *buf++ = OPT_HOSTNAME; *buf++ = (byte)hostnameLength; for (int i = 0; i < hostnameLength; i++) { *buf++ = (byte)hostname[i]; } packet->end += 10; buf = packet->buffer + packet->end; *buf++ = OPT_SERVER_ID; *buf++ = 4; for (int i = 0; i < 4; i++) { *buf++ = ip[i]; } packet->end += 6; /** * Choose what we want to receive */ buf = packet->buffer + packet->end; *buf++ = OPT_PARAMETER_REQUEST; // OPT_PARAMETER_REQUEST *buf++ = 4; // Length of 4 :) *buf++ = OPT_SUBNET; // SUBNET *buf++ = OPT_ROUTER; // ROUTER *buf++ = OPT_NTP; // NTP *buf++ = OPT_DNS; // DNS *buf++ = OPT_END; // And then packet->end += 14; for (int i = 0; i < 4; i++) { tmp[i] = 0xFF; } UDP.Send(packet, tmp, 68, 67); NetPacket.Free(packet); Heap.Free(tmp); }
/// <summary> /// Handle ack /// </summary> /// <param name="buffer">The buffer</param> /// <param name="maxsize">Maximum size</param> private static unsafe void handleAck(byte *buffer, uint maxsize) { DHCPBootstrapHeader *header = (DHCPBootstrapHeader *)buffer; /** * Do not send us anymore! */ if (header->YourClientIP[0] == 0x00) { return; } for (int i = 0; i < 4; i++) { Network.Settings->IP[i] = header->YourClientIP[i]; } int offset = sizeof(DHCPBootstrapHeader) + 4; /** * Loop through options */ while (offset < maxsize && buffer[offset] != OPT_END) { byte type = buffer[offset]; switch (type) { case OPT_SERVER_ID: for (int i = 0; i < 4; i++) { Network.Settings->ServerID[i] = buffer[offset + 2 + i]; } break; case OPT_ROUTER: for (int i = 0; i < 4; i++) { Network.Settings->Gateway[i] = buffer[offset + 2 + i]; } Route.SetGateway(Util.PtrToArray(Network.Settings->Gateway)); break; case OPT_SUBNET: for (int i = 0; i < 4; i++) { Network.Settings->Subnet[i] = buffer[offset + 2 + i]; } break; case OPT_DNS: { byte len = buffer[offset + 1]; for (int i = 0; i < 4; i++) { Network.Settings->DNS1[i] = buffer[offset + 2 + i]; } // More then 1 DNS? if (len > 4) { for (int i = 0; i < 4; i++) { Network.Settings->DNS2[i] = buffer[offset + 4 + i]; } } break; } } offset += buffer[offset + 1] + 2; } Console.Write("[DHCP] dhcp assigned us ip: "); for (int i = 0; i < 3; i++) { Console.WriteNum(Network.Settings->IP[i]); Console.Write('.'); } Console.WriteNum(Network.Settings->IP[3]); Console.Write('\n'); }