add all files from Hong

This commit is contained in:
zhangsz
2025-06-30 09:23:28 +08:00
parent ceb1fe2640
commit 9b7d32fbd9
69 changed files with 7280 additions and 0 deletions

5
cmds/client/README.md Normal file
View File

@@ -0,0 +1,5 @@
# DHCPv6 debug client
This is a simple dhcpv6 client for use as a debugging tool with coredhcp
***This is not a general-purpose DHCP client. This is only a testing/debugging tool for developing CoreDHCP***

61
cmds/client/main.go Normal file
View File

@@ -0,0 +1,61 @@
// Copyright 2018-present the CoreDHCP Authors. All rights reserved
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
package main
/*
* Sample DHCPv6 client to test on the local interface
*/
import (
"flag"
"net"
"github.com/coredhcp/coredhcp/logger"
"github.com/insomniacslk/dhcp/dhcpv6"
"github.com/insomniacslk/dhcp/dhcpv6/client6"
"github.com/insomniacslk/dhcp/iana"
)
var log = logger.GetLogger("main")
func main() {
flag.Parse()
var macString string
if len(flag.Args()) > 0 {
macString = flag.Arg(0)
} else {
macString = "00:11:22:33:44:55"
}
c := client6.NewClient()
c.LocalAddr = &net.UDPAddr{
IP: net.ParseIP("::1"),
Port: 546,
}
c.RemoteAddr = &net.UDPAddr{
IP: net.ParseIP("::1"),
Port: 547,
}
log.Printf("%+v", c)
mac, err := net.ParseMAC(macString)
if err != nil {
log.Fatal(err)
}
duid := dhcpv6.DUIDLLT{
HWType: iana.HWTypeEthernet,
Time: dhcpv6.GetTime(),
LinkLayerAddr: mac,
}
conv, err := c.Exchange("lo", dhcpv6.WithClientID(&duid))
for _, p := range conv {
log.Print(p.Summary())
}
if err != nil {
log.Fatal(err)
}
}

View File

@@ -0,0 +1,40 @@
## CoreDHCP Generator
`coredhcp-generator` is a tool used to build CoreDHCP with the plugins you want.
Why is it even needed? Go is a compiled language with no dynamic loading
support. In order to load a plugin, it has to be compiled in. We are happy to
provide a standard [main.go](/cmds/coredhcp/main.go), and at the same time we
don't want to include plugins that not everyone would use, otherwise the binary
size would grow without control.
You can use `coredhcp-generator` to generate a `main.go` that includes all the
plugins you wish. Just use it as follows:
```
$ ./coredhcp-generator --from core-plugins.txt
2019/11/21 23:32:04 Generating output file '/tmp/coredhcp547019106/coredhcp.go' with 7 plugin(s):
2019/11/21 23:32:04 1) github.com/coredhcp/coredhcp/plugins/file
2019/11/21 23:32:04 2) github.com/coredhcp/coredhcp/plugins/lease_time
2019/11/21 23:32:04 3) github.com/coredhcp/coredhcp/plugins/netmask
2019/11/21 23:32:04 4) github.com/coredhcp/coredhcp/plugins/range
2019/11/21 23:32:04 5) github.com/coredhcp/coredhcp/plugins/router
2019/11/21 23:32:04 6) github.com/coredhcp/coredhcp/plugins/server_id
2019/11/21 23:32:04 7) github.com/coredhcp/coredhcp/plugins/dns
2019/11/21 23:32:04 Generated file '/tmp/coredhcp547019106/coredhcp.go'. You can build it by running 'go build' in the output directory.
```
You can also specify the plugin list on the command line, or mix it with
`--from`:
```
$ ./coredhcp-generator --from core-plugins.txt \
github.com/coredhcp/plugins/redis
```
Notice that it created a file called `coredhcp.go` in a temporary directory. You
can now `go build` that file and have your own custom CoreDHCP.
## Bugs
CoreDHCP uses Go versioned modules. The generated file does not do that yet. We
will add this feature soon.

View File

@@ -0,0 +1,15 @@
github.com/coredhcp/coredhcp/plugins/autoconfigure
github.com/coredhcp/coredhcp/plugins/dns
github.com/coredhcp/coredhcp/plugins/file
github.com/coredhcp/coredhcp/plugins/ipv6only
github.com/coredhcp/coredhcp/plugins/leasetime
github.com/coredhcp/coredhcp/plugins/mtu
github.com/coredhcp/coredhcp/plugins/netmask
github.com/coredhcp/coredhcp/plugins/nbp
github.com/coredhcp/coredhcp/plugins/prefix
github.com/coredhcp/coredhcp/plugins/range
github.com/coredhcp/coredhcp/plugins/router
github.com/coredhcp/coredhcp/plugins/serverid
github.com/coredhcp/coredhcp/plugins/searchdomains
github.com/coredhcp/coredhcp/plugins/sleep
github.com/coredhcp/coredhcp/plugins/staticroute

View File

@@ -0,0 +1,104 @@
// Copyright 2018-present the CoreDHCP Authors. All rights reserved
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
{{/* This file is the template source. The following comment obviously doesn't apply here */ -}}
// This is a generated file, edits should be made in the corresponding source file
// And this file regenerated using `coredhcp-generator --from core-plugins.txt`
package main
import (
"fmt"
"io"
"os"
"github.com/coredhcp/coredhcp/config"
"github.com/coredhcp/coredhcp/logger"
"github.com/coredhcp/coredhcp/server"
"github.com/coredhcp/coredhcp/plugins"
{{- range $plugin := .}}
{{- /* We import all plugins as pl_<pluginname> to avoid conflicts with reserved keywords */}}
{{importname $plugin}} "{{$plugin}}"
{{- end}}
"github.com/sirupsen/logrus"
flag "github.com/spf13/pflag"
)
var (
flagLogFile = flag.StringP("logfile", "l", "", "Name of the log file to append to. Default: stdout/stderr only")
flagLogNoStdout = flag.BoolP("nostdout", "N", false, "Disable logging to stdout/stderr")
flagLogLevel = flag.StringP("loglevel", "L", "info", fmt.Sprintf("Log level. One of %v", getLogLevels()))
flagConfig = flag.StringP("conf", "c", "", "Use this configuration file instead of the default location")
flagPlugins = flag.BoolP("plugins", "P", false, "list plugins")
)
var logLevels = map[string]func(*logrus.Logger){
"none": func(l *logrus.Logger) { l.SetOutput(io.Discard) },
"debug": func(l *logrus.Logger) { l.SetLevel(logrus.DebugLevel) },
"info": func(l *logrus.Logger) { l.SetLevel(logrus.InfoLevel) },
"warning": func(l *logrus.Logger) { l.SetLevel(logrus.WarnLevel) },
"error": func(l *logrus.Logger) { l.SetLevel(logrus.ErrorLevel) },
"fatal": func(l *logrus.Logger) { l.SetLevel(logrus.FatalLevel) },
}
func getLogLevels() []string {
var levels []string
for k := range logLevels {
levels = append(levels, k)
}
return levels
}
var desiredPlugins = []*plugins.Plugin{
{{- range $plugin := .}}
&{{importname $plugin}}.Plugin,
{{- end}}
}
func main() {
flag.Parse()
if *flagPlugins {
for _, p := range desiredPlugins {
fmt.Println(p.Name)
}
os.Exit(0)
}
log := logger.GetLogger("main")
fn, ok := logLevels[*flagLogLevel]
if !ok {
log.Fatalf("Invalid log level '%s'. Valid log levels are %v", *flagLogLevel, getLogLevels())
}
fn(log.Logger)
log.Infof("Setting log level to '%s'", *flagLogLevel)
if *flagLogFile != "" {
log.Infof("Logging to file %s", *flagLogFile)
logger.WithFile(log, *flagLogFile)
}
if *flagLogNoStdout {
log.Infof("Disabling logging to stdout/stderr")
logger.WithNoStdOutErr(log)
}
config, err := config.Load(*flagConfig)
if err != nil {
log.Fatalf("Failed to load configuration: %v", err)
}
// register plugins
for _, plugin := range desiredPlugins {
if err := plugins.RegisterPlugin(plugin); err != nil {
log.Fatalf("Failed to register plugin '%s': %v", plugin.Name, err)
}
}
// start server
srv, err := server.Start(config)
if err != nil {
log.Fatal(err)
}
if err := srv.Wait(); err != nil {
log.Error(err)
}
}

View File

@@ -0,0 +1,144 @@
// Copyright 2018-present the CoreDHCP Authors. All rights reserved
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
package main
import (
"bufio"
"fmt"
"html/template"
"log"
"os"
"path"
"sort"
"strings"
flag "github.com/spf13/pflag"
)
const (
defaultTemplateFile = "coredhcp.go.template"
importBase = "github.com/coredhcp/coredhcp/"
)
var (
flagTemplate = flag.StringP("template", "t", defaultTemplateFile, "Template file name")
flagOutfile = flag.StringP("outfile", "o", "", "Output file path")
flagFromFile = flag.StringP("from", "f", "", "Optional file name to get the plugin list from, one import path per line")
)
var funcMap = template.FuncMap{
"importname": func(importPath string) (string, error) {
parts := strings.Split(importPath, "/")
if len(parts) < 1 {
return "", fmt.Errorf("no components found in import path '%s'", importPath)
}
return "pl_" + parts[len(parts)-1], nil
},
}
func usage() {
fmt.Fprintf(flag.CommandLine.Output(),
"%s [-template tpl] [-outfile out] [-from pluginlist] [plugin [plugin...]]\n",
os.Args[0],
)
flag.PrintDefaults()
fmt.Fprintln(flag.CommandLine.Output(), ` plugin
Plugin name to include, as go import path.
Short names can be used for builtin coredhcp plugins (eg "serverid")`)
}
func main() {
flag.Usage = usage
flag.Parse()
data, err := os.ReadFile(*flagTemplate)
if err != nil {
log.Fatalf("Failed to read template file '%s': %v", *flagTemplate, err)
}
t, err := template.New("coredhcp").Funcs(funcMap).Parse(string(data))
if err != nil {
log.Fatalf("Template parsing failed: %v", err)
}
plugins := make(map[string]bool)
for _, pl := range flag.Args() {
pl := strings.TrimSpace(pl)
if pl == "" {
continue
}
if !strings.ContainsRune(pl, '/') {
// A bare name was specified, not a full import path.
// Coredhcp plugins aren't in the standard library, and it's unlikely someone
// would put them at the base of $GOPATH/src.
// Assume this is one of the builtin plugins. If needed, use the -from option
// which always requires (and uses) exact paths
// XXX: we could also look into github.com/coredhcp/plugins
pl = importBase + pl
}
plugins[pl] = true
}
if *flagFromFile != "" {
// additional plugin names from a text file, one line per plugin import
// path
fd, err := os.Open(*flagFromFile)
if err != nil {
log.Fatalf("Failed to read file '%s': %v", *flagFromFile, err)
}
defer func() {
if err := fd.Close(); err != nil {
log.Printf("Error closing file '%s': %v", *flagFromFile, err)
}
}()
sc := bufio.NewScanner(fd)
for sc.Scan() {
pl := strings.TrimSpace(sc.Text())
if pl == "" {
continue
}
plugins[pl] = true
}
if err := sc.Err(); err != nil {
log.Fatalf("Error reading file '%s': %v", *flagFromFile, err)
}
}
if len(plugins) == 0 {
log.Fatalf("No plugin specified!")
}
outfile := *flagOutfile
if outfile == "" {
tmpdir, err := os.MkdirTemp("", "coredhcp")
if err != nil {
log.Fatalf("Cannot create temporary directory: %v", err)
}
outfile = path.Join(tmpdir, "coredhcp.go")
}
log.Printf("Generating output file '%s' with %d plugin(s):", outfile, len(plugins))
idx := 1
for pl := range plugins {
log.Printf("% 3d) %s", idx, pl)
idx++
}
outFD, err := os.OpenFile(outfile, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Fatalf("Failed to create output file '%s': %v", outfile, err)
}
defer func() {
if err := outFD.Close(); err != nil {
log.Printf("Error while closing file descriptor for '%s': %v", outfile, err)
}
}()
// WARNING: no escaping of the provided strings is done
pluginList := make([]string, 0, len(plugins))
for pl := range plugins {
pluginList = append(pluginList, pl)
}
sort.Strings(pluginList)
if err := t.Execute(outFD, pluginList); err != nil {
log.Fatalf("Template execution failed: %v", err)
}
log.Printf("Generated file '%s'. You can build it by running 'go build' in the output directory.", outfile)
fmt.Println(path.Dir(outfile))
}

167
cmds/coredhcp/config.yml Normal file
View File

@@ -0,0 +1,167 @@
# CoreDHCP configuration (yaml)
# In this file, lines starting with "## " represent default values,
# while uncommented lines are examples which have no default value
# The base level configuration has two sections, one for each protocol version
# (DHCPv4 and DHCPv6). There is no shared configuration at the moment.
# At a high level, both accept the same structure of configuration
# DHCPv6 configuration
#server6:
# listen is an optional section to specify how the server binds to an
# interface or address.
# If unset, the server will join the link-layer multicast group for all
# dhcp servers and relays on each interface, as well as the site-scoped
# multicast group for all dhcp servers.
# Note that in this default configuration the server will not handle
# unicast datagrams, and is equivalent to:
## listen:
## - "[ff02::1:2]"
## - "[ff05::1:3]"
# In general, listen takes a list of addresses, with the general syntax
# "[address%interface]:port", where each part is optional.
# Omitting the address results in the wildcard address being used
# Omitting the interface skips binding the listener to a specific interface
# and listens on all interfaces instead
# Omitting the port uses the default port for DHCPv6 (547)
#
# For example:
# - "[::]"
# Listen on the wildcard address on all interfaces on the default port.
# Note that no multicast group will be joined, so this will *not* work with
# most clients
#
# - ":44480"
# Listens on the wildcard address on a specific port. This can be used if
# you have a relay setup that can contact this server using unicast
#
# - "[::%eno1]"
# Listens on the wildcard address on one interface. This can be used if you
# want to spawn multiple servers with different configurations for multiple
# interfaces, behind a relay that can use unicast
#
# There are some special considerations for multicast:
# - "[ff02::1:2%eno1]"
# Listens on a link-layer multicast address bound to an interface. Also
# used to spawn multiple servers, but for clients on the same subnet
#
# - "[ff05::1:3%eno1]"
# Joining a multicast group with an interface allows to skip the default
# routing table when responding to clients, which can be useful if
# multicast is not otherwise configured system-wide
#
# - "[ff02::1:2]"
# Using a multicast address without an interface will be auto-expanded, so
# that it listens on all available interfaces
# plugins is a mandatory section, which defines how requests are handled.
# It is a list of maps, matching plugin names to their arguments.
# The order is meaningful, as incoming requests are handled by each plugin
# in turn. There is no default value for a plugin configuration, and a
# plugin that is not mentioned will not be loaded at all
#
# The following contains examples of the most common, builtin plugins.
# External plugins should document their arguments in their own
# documentations or readmes
#plugins:
# server_id is mandatory for RFC-compliant operation.
# - server_id: <DUID format> <LL address>
# The supported DUID formats are LL and LLT
#- server_id: LL 00:de:ad:be:ef:00
# file serves leases defined in a static file, matching link-layer addresses to IPs
# - file: <file name> [autorefresh]
# The file format is one lease per line, "<hw address> <IPv6>"
# When the 'autorefresh' argument is given, the plugin will try to refresh
# the lease mapping during runtime whenever the lease file is updated.
#- file: "leases.txt"
# dns adds information about available DNS resolvers to the responses
# - dns: <resolver IP> <... resolver IPs>
#- dns: 2001:4860:4860::8888 2001:4860:4860::8844
# nbp can add information about the location of a network boot program
# - nbp: <NBP URL>
#- nbp: "http://[2001:db8:a::1]/nbp"
# prefix provides prefix delegation.
# - prefix: <prefix> <allocation size>
# prefix is the prefix pool from which the allocations will be carved
# allocation size is the maximum size for prefixes that will be allocated to clients
# EG for allocating /64 or smaller prefixes within 2001:db8::/48 :
#- prefix: 2001:db8::/48 64
# DHCPv4 configuration
server4:
# listen is an optional section to specify how the server binds to an
# interface or address.
# If unset, the server will listen on the broadcast address on all
# interfaces, equivalent to:
## listen:
## - "0.0.0.0"
# In general, listen takes a list of addresses, with the general syntax
# "address%interface:port", where each part is optional.
# * Omitting the address results in the wildcard address being used
# * Omitting the interface skips binding the listener to a specific interface
# and listens on all interfaces instead
# * Omitting the port uses the default port for DHCPv4 (67)
#
# For example:
# - ":44480" Listens on a specific port.
# - "%eno1" Listens on the wildcard address on one interface.
# - "192.0.2.1%eno1:44480" with all parts
# plugins is a mandatory section, which defines how requests are handled.
# It is a list of maps, matching plugin names to their arguments.
# The order is meaningful, as incoming requests are handled by each plugin
# in turn. There is no default value for a plugin configuration, and a
# plugin that is not mentioned will not be loaded at all
#
# The following contains examples of the most common, builtin plugins.
# External plugins should document their arguments in their own
# documentations or readmes
plugins:
# lease_time sets the default lease time for advertised leases
# - lease_time: <duration>
# The duration can be given in any format understood by go's
# "ParseDuration": https://golang.org/pkg/time/#ParseDuration
- lease_time: 3600s
# server_id advertises a DHCP Server Identifier, to help resolve
# situations where there are multiple DHCP servers on the network
# - server_id: <IP address>
# The IP address should be one address where this server is reachable
- server_id: 10.10.10.1
# dns advertises DNS resolvers usable by the clients on this network
# - dns: <IP address> <...IP addresses>
- dns: 8.8.8.8 8.8.4.4
# router is mandatory, and advertises the address of the default router
# for this network
# - router: <IP address>
- router: 192.168.1.1
# netmask advertises the network mask for the IPs assigned through this
# server
# - netmask: <network mask>
- netmask: 255.255.255.0
# range allocates leases within a range of IPs
# - range: <lease file> <start IP> <end IP> <lease duration>
# * the lease file is an initially empty file where the leases that are
# allocated to clients will be stored across server restarts
# * lease duration can be given in any format understood by go's
# "ParseDuration": https://golang.org/pkg/time/#ParseDuration
- range: leases.txt 10.10.10.100 10.10.10.200 60s
# staticroute advertises additional routes the client should install in
# its routing table as described in RFC3442
# - staticroute: <destination>,<gateway> [<destination>,<gateway> ...]
# where destination should be in CIDR notation and gateway should be
# the IP address of the router through which the destination is reachable
# - staticroute: 10.20.20.0/24,10.10.10.1

View File

@@ -0,0 +1,167 @@
# CoreDHCP configuration (yaml)
# In this file, lines starting with "## " represent default values,
# while uncommented lines are examples which have no default value
# The base level configuration has two sections, one for each protocol version
# (DHCPv4 and DHCPv6). There is no shared configuration at the moment.
# At a high level, both accept the same structure of configuration
# DHCPv6 configuration
server6:
# listen is an optional section to specify how the server binds to an
# interface or address.
# If unset, the server will join the link-layer multicast group for all
# dhcp servers and relays on each interface, as well as the site-scoped
# multicast group for all dhcp servers.
# Note that in this default configuration the server will not handle
# unicast datagrams, and is equivalent to:
## listen:
## - "[ff02::1:2]"
## - "[ff05::1:3]"
# In general, listen takes a list of addresses, with the general syntax
# "[address%interface]:port", where each part is optional.
# Omitting the address results in the wildcard address being used
# Omitting the interface skips binding the listener to a specific interface
# and listens on all interfaces instead
# Omitting the port uses the default port for DHCPv6 (547)
#
# For example:
# - "[::]"
# Listen on the wildcard address on all interfaces on the default port.
# Note that no multicast group will be joined, so this will *not* work with
# most clients
#
# - ":44480"
# Listens on the wildcard address on a specific port. This can be used if
# you have a relay setup that can contact this server using unicast
#
# - "[::%eno1]"
# Listens on the wildcard address on one interface. This can be used if you
# want to spawn multiple servers with different configurations for multiple
# interfaces, behind a relay that can use unicast
#
# There are some special considerations for multicast:
# - "[ff02::1:2%eno1]"
# Listens on a link-layer multicast address bound to an interface. Also
# used to spawn multiple servers, but for clients on the same subnet
#
# - "[ff05::1:3%eno1]"
# Joining a multicast group with an interface allows to skip the default
# routing table when responding to clients, which can be useful if
# multicast is not otherwise configured system-wide
#
# - "[ff02::1:2]"
# Using a multicast address without an interface will be auto-expanded, so
# that it listens on all available interfaces
# plugins is a mandatory section, which defines how requests are handled.
# It is a list of maps, matching plugin names to their arguments.
# The order is meaningful, as incoming requests are handled by each plugin
# in turn. There is no default value for a plugin configuration, and a
# plugin that is not mentioned will not be loaded at all
#
# The following contains examples of the most common, builtin plugins.
# External plugins should document their arguments in their own
# documentations or readmes
plugins:
# server_id is mandatory for RFC-compliant operation.
# - server_id: <DUID format> <LL address>
# The supported DUID formats are LL and LLT
- server_id: LL 00:de:ad:be:ef:00
# file serves leases defined in a static file, matching link-layer addresses to IPs
# - file: <file name> [autorefresh]
# The file format is one lease per line, "<hw address> <IPv6>"
# When the 'autorefresh' argument is given, the plugin will try to refresh
# the lease mapping during runtime whenever the lease file is updated.
- file: "leases.txt"
# dns adds information about available DNS resolvers to the responses
# - dns: <resolver IP> <... resolver IPs>
- dns: 2001:4860:4860::8888 2001:4860:4860::8844
# nbp can add information about the location of a network boot program
# - nbp: <NBP URL>
- nbp: "http://[2001:db8:a::1]/nbp"
# prefix provides prefix delegation.
# - prefix: <prefix> <allocation size>
# prefix is the prefix pool from which the allocations will be carved
# allocation size is the maximum size for prefixes that will be allocated to clients
# EG for allocating /64 or smaller prefixes within 2001:db8::/48 :
- prefix: 2001:db8::/48 64
# DHCPv4 configuration
server4:
# listen is an optional section to specify how the server binds to an
# interface or address.
# If unset, the server will listen on the broadcast address on all
# interfaces, equivalent to:
## listen:
## - "0.0.0.0"
# In general, listen takes a list of addresses, with the general syntax
# "address%interface:port", where each part is optional.
# * Omitting the address results in the wildcard address being used
# * Omitting the interface skips binding the listener to a specific interface
# and listens on all interfaces instead
# * Omitting the port uses the default port for DHCPv4 (67)
#
# For example:
# - ":44480" Listens on a specific port.
# - "%eno1" Listens on the wildcard address on one interface.
# - "192.0.2.1%eno1:44480" with all parts
# plugins is a mandatory section, which defines how requests are handled.
# It is a list of maps, matching plugin names to their arguments.
# The order is meaningful, as incoming requests are handled by each plugin
# in turn. There is no default value for a plugin configuration, and a
# plugin that is not mentioned will not be loaded at all
#
# The following contains examples of the most common, builtin plugins.
# External plugins should document their arguments in their own
# documentations or readmes
plugins:
# lease_time sets the default lease time for advertised leases
# - lease_time: <duration>
# The duration can be given in any format understood by go's
# "ParseDuration": https://golang.org/pkg/time/#ParseDuration
- lease_time: 3600s
# server_id advertises a DHCP Server Identifier, to help resolve
# situations where there are multiple DHCP servers on the network
# - server_id: <IP address>
# The IP address should be one address where this server is reachable
- server_id: 10.10.10.1
# dns advertises DNS resolvers usable by the clients on this network
# - dns: <IP address> <...IP addresses>
- dns: 8.8.8.8 8.8.4.4
# router is mandatory, and advertises the address of the default router
# for this network
# - router: <IP address>
- router: 192.168.1.1
# netmask advertises the network mask for the IPs assigned through this
# server
# - netmask: <network mask>
- netmask: 255.255.255.0
# range allocates leases within a range of IPs
# - range: <lease file> <start IP> <end IP> <lease duration>
# * the lease file is an initially empty file where the leases that are
# allocated to clients will be stored across server restarts
# * lease duration can be given in any format understood by go's
# "ParseDuration": https://golang.org/pkg/time/#ParseDuration
- range: leases.txt 10.10.10.100 10.10.10.200 60s
# staticroute advertises additional routes the client should install in
# its routing table as described in RFC3442
# - staticroute: <destination>,<gateway> [<destination>,<gateway> ...]
# where destination should be in CIDR notation and gateway should be
# the IP address of the router through which the destination is reachable
# - staticroute: 10.20.20.0/24,10.10.10.1

BIN
cmds/coredhcp/coredhcp Executable file

Binary file not shown.

View File

@@ -0,0 +1 @@
00:11:22:33:44:55 2001:2::1

BIN
cmds/coredhcp/leases.txt Normal file

Binary file not shown.

129
cmds/coredhcp/main.go Normal file
View File

@@ -0,0 +1,129 @@
// Copyright 2018-present the CoreDHCP Authors. All rights reserved
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
// This is a generated file, edits should be made in the corresponding source file
// And this file regenerated using `coredhcp-generator --from core-plugins.txt`
package main
import (
"fmt"
"io"
"os"
"github.com/coredhcp/coredhcp/config"
grpcServer "github.com/coredhcp/coredhcp/grpc_server"
"github.com/coredhcp/coredhcp/logger"
"github.com/coredhcp/coredhcp/server"
"github.com/coredhcp/coredhcp/plugins"
pl_autoconfigure "github.com/coredhcp/coredhcp/plugins/autoconfigure"
pl_dns "github.com/coredhcp/coredhcp/plugins/dns"
pl_file "github.com/coredhcp/coredhcp/plugins/file"
pl_ipv6only "github.com/coredhcp/coredhcp/plugins/ipv6only"
pl_leasetime "github.com/coredhcp/coredhcp/plugins/leasetime"
pl_mtu "github.com/coredhcp/coredhcp/plugins/mtu"
pl_nbp "github.com/coredhcp/coredhcp/plugins/nbp"
pl_netmask "github.com/coredhcp/coredhcp/plugins/netmask"
pl_prefix "github.com/coredhcp/coredhcp/plugins/prefix"
pl_range "github.com/coredhcp/coredhcp/plugins/range"
pl_router "github.com/coredhcp/coredhcp/plugins/router"
pl_searchdomains "github.com/coredhcp/coredhcp/plugins/searchdomains"
pl_serverid "github.com/coredhcp/coredhcp/plugins/serverid"
pl_sleep "github.com/coredhcp/coredhcp/plugins/sleep"
pl_staticroute "github.com/coredhcp/coredhcp/plugins/staticroute"
"github.com/sirupsen/logrus"
flag "github.com/spf13/pflag"
)
var (
flagLogFile = flag.StringP("logfile", "l", "", "Name of the log file to append to. Default: stdout/stderr only")
flagLogNoStdout = flag.BoolP("nostdout", "N", false, "Disable logging to stdout/stderr")
flagLogLevel = flag.StringP("loglevel", "L", "info", fmt.Sprintf("Log level. One of %v", getLogLevels()))
flagConfig = flag.StringP("conf", "c", "", "Use this configuration file instead of the default location")
flagPlugins = flag.BoolP("plugins", "P", false, "list plugins")
)
var logLevels = map[string]func(*logrus.Logger){
"none": func(l *logrus.Logger) { l.SetOutput(io.Discard) },
"debug": func(l *logrus.Logger) { l.SetLevel(logrus.DebugLevel) },
"info": func(l *logrus.Logger) { l.SetLevel(logrus.InfoLevel) },
"warning": func(l *logrus.Logger) { l.SetLevel(logrus.WarnLevel) },
"error": func(l *logrus.Logger) { l.SetLevel(logrus.ErrorLevel) },
"fatal": func(l *logrus.Logger) { l.SetLevel(logrus.FatalLevel) },
}
func getLogLevels() []string {
var levels []string
for k := range logLevels {
levels = append(levels, k)
}
return levels
}
var desiredPlugins = []*plugins.Plugin{
&pl_autoconfigure.Plugin,
&pl_dns.Plugin,
&pl_file.Plugin,
&pl_ipv6only.Plugin,
&pl_leasetime.Plugin,
&pl_mtu.Plugin,
&pl_nbp.Plugin,
&pl_netmask.Plugin,
&pl_prefix.Plugin,
&pl_range.Plugin,
&pl_router.Plugin,
&pl_searchdomains.Plugin,
&pl_serverid.Plugin,
&pl_sleep.Plugin,
&pl_staticroute.Plugin,
}
func main() {
flag.Parse()
if *flagPlugins {
for _, p := range desiredPlugins {
fmt.Println(p.Name)
}
os.Exit(0)
}
log := logger.GetLogger("main")
fn, ok := logLevels[*flagLogLevel]
if !ok {
log.Fatalf("Invalid log level '%s'. Valid log levels are %v", *flagLogLevel, getLogLevels())
}
fn(log.Logger)
log.Infof("Setting log level to '%s'", *flagLogLevel)
if *flagLogFile != "" {
log.Infof("Logging to file %s", *flagLogFile)
logger.WithFile(log, *flagLogFile)
}
if *flagLogNoStdout {
log.Infof("Disabling logging to stdout/stderr")
logger.WithNoStdOutErr(log)
}
config, err := config.Load(*flagConfig)
if err != nil {
log.Fatalf("Failed to load configuration: %v", err)
}
// register plugins
for _, plugin := range desiredPlugins {
if err := plugins.RegisterPlugin(plugin); err != nil {
log.Fatalf("Failed to register plugin '%s': %v", plugin.Name, err)
}
}
go grpcServer.Run()
// start server
srv, err := server.Start(config)
if err != nil {
log.Fatal(err)
}
if err := srv.Wait(); err != nil {
log.Error(err)
}
}