Beispiel #1
0
/*
 * Example Server :D
 */
func ExampleServer() {

	//Create a Lease Pool We're going to use a memory pool
	//Remember the memory is cleared on restart so you will reissue the same IP Addresses.
	myMemoryLeasePool := memorypool.MemoryPool{}

	//Lets add a list of IPs to the pool these will be served to the clients so make sure they work for you.
	// So Create Array of IPs 192.168.1.1 to 192.168.1.30
	for i := 0; i < 30; i++ {
		err := myMemoryLeasePool.AddLease(leasepool.Lease{IP: dhcp4.IPAdd(net.IPv4(192, 168, 1, 1), i)})
		if err != nil {
			log.Fatalln("Error Adding IP to pool:" + err.Error())
		}
	}

	// We set the port numbers to over 1024 (1067 & 1068) as the automated test don't have root access
	tServer, err := dhcp4server.New(
		net.IPv4(192, 168, 1, 201),
		&myMemoryLeasePool,
		dhcp4server.SetLocalAddr(net.UDPAddr{IP: net.IPv4(0, 0, 0, 0), Port: 1067}),
		dhcp4server.SetRemoteAddr(net.UDPAddr{IP: net.IPv4bcast, Port: 1068}),
	)
	if err != nil {
		log.Fatalln("Error Configuring Server:" + err.Error())
	}

	//Start the Server...
	err = tServer.ListenAndServe()
	if err != nil {
		log.Fatalln("Error Starting Server:" + err.Error())
	}
}
Beispiel #2
0
func TestLeaseCycle(test *testing.T) {
	myMemoryLeasePool := MemoryPool{}

	//Lets add a list of IPs to the pool these will be served to the clients so make sure they work for you.
	// So Create Array of IPs 192.168.1.1 to 192.168.1.30
	for i := 0; i < 30; i++ {
		err := myMemoryLeasePool.AddLease(leasepool.Lease{IP: dhcp4.IPAdd(net.IPv4(192, 168, 1, 1), i)})
		if err != nil {
			test.Error("Error Creating Lease:" + err.Error())
		}
	}

	for i := 0; i < 30; i++ {
		hasLease, iLease, err := myMemoryLeasePool.GetNextFreeLease()
		if err != nil || !hasLease {
			test.Error("Error Getting Lease:" + err.Error())
		}

		if !dhcp4.IPAdd(net.IPv4(192, 168, 1, 1), i).Equal(iLease.IP) {
			test.Error("Expected Lease:" + dhcp4.IPAdd(net.IPv4(192, 168, 1, 1), i).String() + " Received:" + iLease.IP.String())
		}
	}
}
Beispiel #3
0
func getTestLeasePool() *memorypool.MemoryPool {
	//Create a Lease Pool We're going to use a memory pool
	//Remember the memory is cleared on restart so you will reissue the same IP Addresses.
	myMemoryLeasePool := memorypool.MemoryPool{}

	//Lets add a list of IPs to the pool these will be served to the clients so make sure they work for you.
	// So Create Array of IPs 192.168.1.1 to 192.168.1.30
	for i := 0; i < 30; i++ {
		err := myMemoryLeasePool.AddLease(leasepool.Lease{IP: dhcp4.IPAdd(net.IPv4(192, 168, 1, 1), i)})
		if err != nil {
			log.Fatalln("Error Adding IP to pool:" + err.Error())
		}
	}
	return &myMemoryLeasePool
}
Beispiel #4
0
func StartDHCPService(configuration *Configuration) {
	//This allows us to deactivate DHCP
	if configuration.DHCP.Disabled {
		log.Println("Warning: DHCP is disabled by configuration (config.json)")
		return
	}

	leasePool, err := datastore.GetLeaseHelper()
	if err != nil {
		log.Fatal("Unable to Start Lease Pool")
	}

	//Lets work out the number of leases
	numLeases := dhcp4.IPRange(net.ParseIP(configuration.DHCP.Leases.Start), net.ParseIP(configuration.DHCP.Leases.End))

	//Lets add a list of IPs to the pool these will be served to the clients so make sure they work for you.
	//So Create Array of IPs 192.168.1.1 to 192.168.1.30
	for i := 0; i < numLeases; i++ {
		err = leasePool.AddLease(leasepool.Lease{IP: dhcp4.IPAdd(net.ParseIP(configuration.DHCP.Leases.Start), i)})
		if err != nil {
			log.Fatalln("Error Adding IPs to pool:" + err.Error())
		}
	}

	//If we don't have an IP configured then use the first Active IP interface (warn if there is more than 1)
	if configuration.DHCP.Server.IP == nil || configuration.DHCP.Server.IP.Equal(net.IPv4(0, 0, 0, 0)) {
		//Get IP And Subnet (Windows doesn't seem to give subnet)
		mainActiveIPNetwork, err := networktools.MainActiveIPNetwork()
		if err != nil {
			log.Fatalln("Error Getting Local Interfaces:" + err.Error())
		}

		if mainActiveIPNetwork.IP.Equal(net.IP{}) {
			log.Fatal("No Interface Found With a Valid IP")
		}

		configuration.DHCP.Server.IP = mainActiveIPNetwork.IP

		if !bytes.Equal(mainActiveIPNetwork.Mask, net.IPMask{}) && (configuration.DHCP.Server.SubnetMask == nil || configuration.DHCP.Server.SubnetMask.Equal(net.IPv4(0, 0, 0, 0))) {
			configuration.DHCP.Server.SubnetMask = net.ParseIP(mainActiveIPNetwork.Mask.String())
		}
	}

	//Make Sure we Now have a Subnet Mask
	if configuration.DHCP.Server.SubnetMask == nil || configuration.DHCP.Server.SubnetMask.Equal(net.IPv4(0, 0, 0, 0)) {
		log.Fatalln("DHCP SubnetMask Missing in Configuration and Unable to Calculate...")
	}

	//If For some reason We've setup alternative DNS servers (I Can't think why we should) use them otherwise add ourself.
	if configuration.DHCP.Server.DNSServers == nil || len(configuration.DHCP.Server.DNSServers) == 0 {
		configuration.DHCP.Server.DNSServers = append(configuration.DHCP.Server.DNSServers, configuration.DHCP.Server.IP)
	} else {
		log.Printf("Warning: Using Preconfigured DNS Servers %v\n", configuration.DHCP.Server.DNSServers)
	}

	//If For some reason We've setup alternative Gateway (I Can't think why we should) use them otherwise add ourself.
	if configuration.DHCP.Server.DefaultGateway == nil {
		configuration.DHCP.Server.DefaultGateway = configuration.DHCP.Server.IP
	} else {
		log.Printf("Warning: Using Preconfigured Default Gateway %v\n", configuration.DHCP.Server.DefaultGateway)
	}

	//Create The Server
	myServer := dhcp4server.Server{}

	myServer.Configuration = &configuration.DHCP.Server
	myServer.LeasePool = leasePool

	//Start GC on the Leases.
	go func() {
		for {
			select {
			case <-time.After(configuration.DHCP.Server.LeaseDuration):
			}

			err := myServer.GC()
			if err != nil {
				log.Printf("Error: DHCP GC Failed Error: \"%v\"\n", err)
				return
			}
		}
	}()

	//Start the Server...
	err = myServer.ListenAndServe()
	if err != nil {
		log.Fatalln("Error Starting Server:" + err.Error())
	}
}
Beispiel #5
0
/*
 * Benchmark the ServeDHCP Function
 */
func BenchmarkServeDHCP(test *testing.B) {
	//Create a Lease Pool We're going to use a memory pool
	//Remember the memory is cleared on restart so you will reissue the same IP Addresses.
	myMemoryLeasePool := memorypool.MemoryPool{}

	//Lets add a list of IPs to the pool these will be served to the clients so make sure they work for you.
	// So Create Array of IPs 192.168.1.1 to 192.168.1.30
	for i := 0; i < test.N; i++ {
		err := myMemoryLeasePool.AddLease(leasepool.Lease{IP: dhcp4.IPAdd(net.IPv4(192, 168, 1, 1), i)})
		if err != nil {
			log.Fatalln("Error Adding IP to pool:" + err.Error())
		}
	}

	//Setup the Server
	myServer, err := dhcp4server.New(
		net.IPv4(127, 0, 0, 1),
		&myMemoryLeasePool,
	)
	if err != nil {
		test.Error("Error: Can't Configure Server " + err.Error())
	}

	//Setup A Client
	// Although We Won't send the packets over the network we'll use the client to create the requests.
	c, err := dhcp4client.NewInetSock(dhcp4client.SetLocalAddr(net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1068}), dhcp4client.SetRemoteAddr(net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1067}))
	if err != nil {
		test.Error("Client Conection Generation:" + err.Error())
	}

	client, err := dhcp4client.New(dhcp4client.Connection(c))
	if err != nil {
		test.Error("Error: Can't Configure Client " + err.Error())
	}
	defer client.Close()

	test.ResetTimer()

	for i := 0; i < test.N; i++ {
		test.StopTimer()
		//Generate Hardware Address
		HardwareMACAddress, err := hardwareaddr.GenerateEUI48()
		if err != nil {
			test.Error("Error: Can't Generate Valid MACAddress" + err.Error())
		}

		client.SetOption(dhcp4client.HardwareAddr(HardwareMACAddress))
		discovery := client.DiscoverPacket()

		//Run the Discovery On the Server
		test.StartTimer()
		offer, err := myServer.ServeDHCP(discovery)
		if err != nil {
			test.Error("Discovery Error:" + err.Error())
		}

		if len(offer) == 0 {
			test.Error("No Valid Offer")
		} else {
			request := client.RequestPacket(&offer)
			_, err := myServer.ServeDHCP(request)
			if err != nil {
				test.Error("Acknowledge Error:" + err.Error())
			}

		}
	}
}
Beispiel #6
0
func TestConsumeLeases(test *testing.T) {
	//Setup the Server
	myServer, err := dhcp4server.New(
		net.IPv4(127, 0, 0, 1),
		getTestLeasePool(),
	)
	if err != nil {
		test.Error("Error: Can't Configure Server " + err.Error())
	}

	// Setup A Client
	// Although We Won't send the packets over the network we'll use the client to create the requests.
	c, err := dhcp4client.NewInetSock(dhcp4client.SetLocalAddr(net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1068}), dhcp4client.SetRemoteAddr(net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1067}))
	if err != nil {
		test.Error("Client Conection Generation:" + err.Error())
	}

	client, err := dhcp4client.New(dhcp4client.Connection(c))
	if err != nil {
		test.Error("Error: Can't Configure Client " + err.Error())
	}
	defer client.Close()

	for i := 0; i < 30; i++ {
		//Generate Hardware Address
		HardwareMACAddress, err := hardwareaddr.GenerateEUI48()
		if err != nil {
			test.Error("Error: Can't Generate Valid MACAddress" + err.Error())
		}

		client.SetOption(dhcp4client.HardwareAddr(HardwareMACAddress))
		test.Log("MAC:" + HardwareMACAddress.String())

		discovery := client.DiscoverPacket()

		//Run the Discovery On the Server
		offer, err := myServer.ServeDHCP(discovery)
		_, err = myServer.ServeDHCP(discovery)
		if err != nil {
			test.Error("Discovery Error:" + err.Error())
		}

		request := client.RequestPacket(&offer)
		acknowledgement, err := myServer.ServeDHCP(request)
		if err != nil {
			test.Error("Acknowledge Error:" + err.Error())
		}

		test.Logf("Received Lease:%v\n", acknowledgement.YIAddr().String())
		if !dhcp4.IPAdd(net.IPv4(192, 168, 1, 1), i).Equal(acknowledgement.YIAddr()) {
			test.Error("Expected IP:" + dhcp4.IPAdd(net.IPv4(192, 168, 1, 1), i).String() + " Received:" + acknowledgement.YIAddr().String())
		}

		//How long the lease is for?
		acknowledgementOptions := acknowledgement.ParseOptions()
		if len(acknowledgementOptions) > 0 {
			test.Logf("Lease Options:%v\n", acknowledgementOptions)
			if acknowledgementOptions[dhcp4.OptionIPAddressLeaseTime] != nil {
				var result uint32
				buf := bytes.NewBuffer(acknowledgementOptions[dhcp4.OptionIPAddressLeaseTime])
				binary.Read(buf, binary.BigEndian, &result)
				test.Logf("Lease Time (Seconds):%d\n", result)
			}
		} else {
			test.Errorf("Lease:\"%v\" Has No Options\n", acknowledgement.YIAddr())
		}
	}
}