public void OnTick(uint tick) { switch (state) { case State.INIT: if (failures <= 10) { offeredIP = null; DHCPServerIP = null; Offer = null; RequestResponce = null; // Create DHCP Options Optionlist ol = new Optionlist(); ol.Add(new DHCPOption(Tag.dhcpMsgType, new byte[1] { (byte)DHCPOption.MsgType.DHCPDISCOVER })); // Requesting Spesific IP if (a.LocalIP != null) { ol.Add(new DHCPOption(Tag.addressRequest, a.LocalIP.ToBytes())); } // Asking for Spesific Params back ol.Add(new DHCPOption(Tag.paramaterList, paramlist.ToArray())); // create DHCP Datagram DHCPDatagram DhcpDatagram = new DHCPDatagram(0, xid, ClientMAC: a.MyMACAddress, Broadcast: true, options: ol); // UDP and IPv4 Headers UDPHeader UDP = new UDPHeader(68, 67, DhcpDatagram.ToBytes()); IPv4Header IPv4 = IPv4Header.DefaultUDPWrapper(IP.Zero, IP.Broadcast, UDP.ToBytes(), 32); state = State.SELECTING; Client.Log("Sending Discover Packet"); // Send IPv4 Packet a.SendPacket(IPv4.ToBytes()); T3 = 100; } break; case State.SELECTING: if (Offer != null) { if (Offer.yiaddr != null) { offeredIP = Offer.yiaddr; DHCPServerIP = null; foreach (DHCPOption o in Offer.options) { if (o.tag == Tag.dhcpServerID) { DHCPServerIP = new IP(o.data); } } Optionlist ol = new Optionlist() { new DHCPOption(Tag.dhcpMsgType, new byte[1] { (byte)DHCPOption.MsgType.DHCPREQUEST }), new DHCPOption(Tag.addressRequest, offeredIP.ToBytes()) }; if (DHCPServerIP != null) { ol.Add(new DHCPOption(Tag.dhcpServerID, DHCPServerIP.ToBytes())); } ol.Add(new DHCPOption(Tag.paramaterList, paramlist.ToArray())); DHCPDatagram DhcpDatagram = new DHCPDatagram(0, xid, ClientMAC: a.MyMACAddress, options: ol); UDPHeader UDP = new UDPHeader(68, 67, DhcpDatagram.ToBytes()); IP server = IP.Broadcast; if (Offer.siaddr != null) { server = Offer.siaddr; } IPv4Header IPv4 = IPv4Header.DefaultUDPWrapper(IP.Zero, server, UDP.ToBytes(), 32); a.SendPacket(IPv4.ToBytes()); Client.Log("Sending Request Packet"); state = State.REQUESTING; } } else if (T3-- <= 0) { failures++; state = State.INIT; } break; case State.REQUESTING: if (RequestResponce != null) { foreach (DHCPOption o in RequestResponce.options) { if (o.tag == Tag.dhcpMsgType) { if (o.data[0] == (byte)DHCPOption.MsgType.DHCPNAK) { Offer = null; RequestResponce = null; state = State.INIT; break; } else if (o.data[0] == (byte)DHCPOption.MsgType.DHCPACK) { foreach (DHCPOption op in RequestResponce.options) { switch (op.tag) { case Tag.addressTime: T1 = BitConverter.ToUInt32(op.data, 0); T2 = T1 - 10; break; case Tag.subnetmask: a.SubnetMask = new IP(op.data, 0); break; case Tag.router: a.DefaultGateway = new IP(op.data, 0); break; case Tag.domainserver: a.DNS = new IP(op.data, 0); break; } } a.LocalIP = RequestResponce.yiaddr; state = State.BOUND; break; } } } } break; case State.BOUND: if (T2-- <= 0) { T1--; Optionlist ol = new Optionlist() { new DHCPOption(Tag.dhcpMsgType, new byte[1] { (byte)DHCPOption.MsgType.DHCPREQUEST }), new DHCPOption(Tag.addressRequest, a.LocalIP.ToBytes()) }; if (DHCPServerIP != null) { ol.Add(new DHCPOption(Tag.dhcpServerID, DHCPServerIP.ToBytes())); } ol.Add(new DHCPOption(Tag.paramaterList, paramlist.ToArray())); DHCPDatagram DhcpDatagram = new DHCPDatagram(0, xid, ClientMAC: a.MyMACAddress, options: ol); UDPHeader UDP = new UDPHeader(68, 67, DhcpDatagram.ToBytes()); IP server = IP.Broadcast; if (Offer.siaddr != null) { server = Offer.siaddr; } IPv4Header IPv4 = IPv4Header.DefaultUDPWrapper(a.LocalIP, server, UDP.ToBytes(), 32); RequestResponce = null; a.SendPacket(IPv4.ToBytes()); state = State.RENEWING; } break; case State.RENEWING: if (RequestResponce != null) { foreach (DHCPOption o in RequestResponce.options) { if (o.tag == Tag.dhcpMsgType) { if (o.data[0] == (byte)DHCPOption.MsgType.DHCPNAK) { Offer = null; state = State.INIT; break; } else if (o.data[0] == (byte)DHCPOption.MsgType.DHCPACK) { foreach (DHCPOption op in RequestResponce.options) { switch (op.tag) { case Tag.addressTime: T1 = BitConverter.ToUInt32(op.data, 0); T2 = T1 - 200; break; case Tag.subnetmask: a.SubnetMask = new IP(op.data, 0); break; case Tag.router: a.DefaultGateway = new IP(op.data, 0); break; case Tag.domainserver: a.DNS = new IP(op.data, 0); break; } } a.LocalIP = RequestResponce.yiaddr; state = State.BOUND; break; } } } } else if (T1-- <= 0) { Optionlist ol = new Optionlist() { new DHCPOption(Tag.dhcpMsgType, new byte[1] { (byte)DHCPOption.MsgType.DHCPREQUEST }), new DHCPOption(Tag.addressRequest, a.LocalIP.ToBytes()) }; if (DHCPServerIP != null) { ol.Add(new DHCPOption(Tag.dhcpServerID, DHCPServerIP.ToBytes())); } ol.Add(new DHCPOption(Tag.paramaterList, paramlist.ToArray())); DHCPDatagram DhcpDatagram = new DHCPDatagram(0, xid, ClientMAC: a.MyMACAddress, options: ol); UDPHeader UDP = new UDPHeader(68, 67, DhcpDatagram.ToBytes()); IP server = IP.Broadcast; if (Offer.siaddr != null) { server = Offer.siaddr; } IPv4Header IPv4 = IPv4Header.DefaultUDPWrapper(a.LocalIP, server, UDP.ToBytes(), 32); state = State.REBINDING; T3 = 200; a.SendPacket(IPv4.ToBytes()); } break; case State.REBINDING: if (RequestResponce != null) { foreach (DHCPOption o in RequestResponce.options) { if (o.tag == Tag.dhcpMsgType) { if (o.data[0] == (byte)DHCPOption.MsgType.DHCPNAK) { Offer = null; state = State.INIT; break; } else if (o.data[0] == (byte)DHCPOption.MsgType.DHCPACK) { foreach (DHCPOption op in RequestResponce.options) { switch (op.tag) { case Tag.addressTime: T1 = BitConverter.ToUInt32(op.data, 0); T2 = T1 - 200; break; case Tag.subnetmask: a.SubnetMask = new IP(op.data, 0); break; case Tag.router: a.DefaultGateway = new IP(op.data, 0); break; case Tag.domainserver: a.DNS = new IP(op.data, 0); break; } } a.LocalIP = RequestResponce.yiaddr; state = State.BOUND; break; } } } } else if (T3-- <= 0) { state = State.INIT; } break; case State.INITREBOOT: state = State.INIT; break; case State.REBOOTING: state = State.INIT; break; } }
public void packet(IPv4Header ipv4, UDPHeader udp, UInt16 dest, NetworkInterface a) { if (dest == 67) { try { DHCPDatagram dHCP = new DHCPDatagram(udp.Datagram); DHCPDatagram newdHCP = new DHCPDatagram(2, dHCP.xid, ClientMAC: dHCP.chaddr); Optionlist ol = new Optionlist(); foreach (DHCPOption o in dHCP.options) { switch (o.tag) { case Tag.paramaterList: foreach (byte b in o.data) { switch ((Tag)b) { case Tag.dhcpServerID: ol.Add(new DHCPOption(Tag.dhcpServerID, a.LocalIP.ToBytes())); break; case Tag.router: ol.Add(new DHCPOption(Tag.router, GatewayIP.ToBytes())); break; case Tag.subnetmask: ol.Add(new DHCPOption(Tag.subnetmask, SubnetMask.ToBytes())); break; case Tag.domainserver: ol.Add(new DHCPOption(Tag.domainserver, DNS.ToBytes())); break; } } break; case Tag.dhcpMsgType: switch ((DHCPOption.MsgType)o.data[0]) { case DHCPOption.MsgType.DHCPDISCOVER: Log("DHCPDescover recieved from " + dHCP.chaddr.ToString()); if (newdHCP == null) { break; } newdHCP.yiaddr = NewAddress(dHCP.chaddr); Reserved.Add(newdHCP.yiaddr, new Lease(newdHCP.yiaddr, dHCP.chaddr, currentTick, 100)); ol.Add(new DHCPOption(Tag.dhcpMsgType, new byte[] { (byte)DHCPOption.MsgType.DHCPOFFER })); Log("Offered IP " + newdHCP.yiaddr + " to " + newdHCP.chaddr); break; case DHCPOption.MsgType.DHCPREQUEST: IP Request = new IP(dHCP.options.Find(match => match.tag == Tag.addressRequest).data, 0); Log("DHCPRequest recieved from " + dHCP.chaddr.ToString()); if (isAvailable(Request, dHCP.chaddr)) { lock (Leaseslock) { if (Reserved.ContainsKey(Request)) { Reserved.Remove(Request); } if (Leases.ContainsKey(Request)) { Leases.Remove(Request); } Lease l = new Lease(Request, dHCP.chaddr, currentTick, (uint)r.Next(40, 60)); Leases.Add(l.ciaddr, l); ol.Add(new DHCPOption(Tag.dhcpMsgType, new byte[] { (byte)DHCPOption.MsgType.DHCPACK })); newdHCP.yiaddr = Request; Log("Leased IP " + l.ciaddr + " to " + l.chaddr + " for " + l.LeaseLength + " ticks"); } } else { ol.Add(new DHCPOption(Tag.dhcpMsgType, new byte[] { (byte)DHCPOption.MsgType.DHCPNAK })); Log("denied lease of " + Request + " to " + dHCP.chaddr); } break; } break; } } newdHCP.options = ol; UDPHeader newupd = new UDPHeader(67, 68, newdHCP.ToBytes()); IPv4Header newipv4 = IPv4Header.DefaultUDPWrapper(a.LocalIP, IP.Broadcast, newupd.ToBytes(), 32); a.SendPacket(newipv4.ToBytes()); Log("Packet Sent"); } catch (Exception e) { Log(e.ToString()); } } }