|
|
@@ -1,155 +0,0 @@
|
|
|
-// 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 redisplugin
|
|
|
-
|
|
|
-import (
|
|
|
- "errors"
|
|
|
- "fmt"
|
|
|
- "net"
|
|
|
- "strings"
|
|
|
- "time"
|
|
|
-
|
|
|
- "github.com/coredhcp/coredhcp/handler"
|
|
|
- "github.com/coredhcp/coredhcp/logger"
|
|
|
- "github.com/coredhcp/coredhcp/plugins"
|
|
|
- "github.com/gomodule/redigo/redis"
|
|
|
- "github.com/insomniacslk/dhcp/dhcpv4"
|
|
|
- "github.com/insomniacslk/dhcp/dhcpv6"
|
|
|
-)
|
|
|
-
|
|
|
-// various global variables
|
|
|
-var (
|
|
|
- log = logger.GetLogger("plugins/redis")
|
|
|
- pool *redis.Pool
|
|
|
-)
|
|
|
-
|
|
|
-func init() {
|
|
|
- plugins.RegisterPlugin("redis", setupRedis6, setupRedis4)
|
|
|
-}
|
|
|
-
|
|
|
-// Handler6 handles DHCPv6 packets for the redis plugin
|
|
|
-func Handler6(req, resp dhcpv6.DHCPv6) (dhcpv6.DHCPv6, bool) {
|
|
|
- // TODO add IPv6 support
|
|
|
- return nil, true
|
|
|
-}
|
|
|
-
|
|
|
-// Handler4 handles DHCPv4 packets for the redis plugin
|
|
|
-func Handler4(req, resp *dhcpv4.DHCPv4) (*dhcpv4.DHCPv4, bool) {
|
|
|
- // Get redis connection from pool
|
|
|
- conn := pool.Get()
|
|
|
-
|
|
|
- // defer redis connection close so we don't leak connections
|
|
|
- defer conn.Close()
|
|
|
-
|
|
|
- // Get all options for a MAC
|
|
|
- options, err := redis.StringMap(conn.Do("HGETALL", "mac:"+req.ClientHWAddr.String()))
|
|
|
-
|
|
|
- // Handle redis error
|
|
|
- if err != nil {
|
|
|
- log.Printf("Redis error: %s...dropping request", err)
|
|
|
- return nil, true
|
|
|
- }
|
|
|
-
|
|
|
- // Handle no hash found
|
|
|
- if len(options) == 0 {
|
|
|
- log.Printf("MAC %s not found...dropping request", req.ClientHWAddr.String())
|
|
|
- return nil, true
|
|
|
- }
|
|
|
-
|
|
|
- // Handle no ipv4 field
|
|
|
- if options["ipv4"] == "" {
|
|
|
- log.Printf("MAC %s has no ipv4 field...dropping request", req.ClientHWAddr.String())
|
|
|
- return nil, true
|
|
|
- }
|
|
|
-
|
|
|
- // Loop through options returned and assign as needed
|
|
|
- for option, value := range options {
|
|
|
- switch option {
|
|
|
- case "ipv4":
|
|
|
- ipaddr, ipnet, err := net.ParseCIDR(value)
|
|
|
- if err != nil {
|
|
|
- log.Printf("MAC %s malformed IP %s error: %s...dropping request", req.ClientHWAddr.String(), value, err)
|
|
|
- return nil, true
|
|
|
- }
|
|
|
- resp.YourIPAddr = ipaddr
|
|
|
- resp.Options.Update(dhcpv4.OptSubnetMask(ipnet.Mask))
|
|
|
- log.Printf("MAC %s assigned IPv4 address %s", req.ClientHWAddr.String(), value)
|
|
|
-
|
|
|
- case "router":
|
|
|
- router := net.ParseIP(value)
|
|
|
- if router.To4() == nil {
|
|
|
- log.Printf("MAC %s Invalid router option: %s...option skipped", req.ClientHWAddr.String(), value)
|
|
|
- break
|
|
|
- }
|
|
|
- resp.Options.Update(dhcpv4.OptRouter(router))
|
|
|
-
|
|
|
- case "dns":
|
|
|
- var dnsServers4 []net.IP
|
|
|
- servers := strings.Split(value, ",")
|
|
|
- for _, server := range servers {
|
|
|
- DNSServer := net.ParseIP(server)
|
|
|
- if DNSServer.To4() == nil {
|
|
|
- log.Printf("MAC %s Invalid dns server: %s...dropping request", req.ClientHWAddr.String(), server)
|
|
|
- return nil, true
|
|
|
- }
|
|
|
- dnsServers4 = append(dnsServers4, DNSServer)
|
|
|
- }
|
|
|
- if req.IsOptionRequested(dhcpv4.OptionDomainNameServer) {
|
|
|
- resp.Options.Update(dhcpv4.OptDNS(dnsServers4...))
|
|
|
- }
|
|
|
-
|
|
|
- case "leaseTime":
|
|
|
- lt, err := time.ParseDuration(value)
|
|
|
- if err != nil {
|
|
|
- log.Printf("MAC %s invalid lease time %s...option skipped", req.ClientHWAddr.String(), value)
|
|
|
- break
|
|
|
- }
|
|
|
- // Set lease time
|
|
|
- resp.Options.Update(dhcpv4.OptIPAddressLeaseTime(lt))
|
|
|
-
|
|
|
- default:
|
|
|
- log.Printf("MAC %s found un-handled option %s...option skipped", req.ClientHWAddr.String(), option)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return resp, false
|
|
|
-}
|
|
|
-
|
|
|
-func setupRedis6(args ...string) (handler.Handler6, error) {
|
|
|
- // TODO setup function for IPv6
|
|
|
- log.Warning("not implemented for IPv6")
|
|
|
- return Handler6, nil
|
|
|
-}
|
|
|
-
|
|
|
-func setupRedis4(args ...string) (handler.Handler4, error) {
|
|
|
- _, h4, err := setupRedis(false, args...)
|
|
|
- return h4, err
|
|
|
-}
|
|
|
-
|
|
|
-func setupRedis(v6 bool, args ...string) (handler.Handler6, handler.Handler4, error) {
|
|
|
- if len(args) < 1 {
|
|
|
- return nil, nil, fmt.Errorf("invalid number of arguments, want: 1 (redis server:port), got: %d", len(args))
|
|
|
- }
|
|
|
- if args[0] == "" {
|
|
|
- return nil, nil, errors.New("Redis server can't be empty")
|
|
|
- }
|
|
|
-
|
|
|
- if v6 {
|
|
|
- log.Printf("Using redis server %s for DHCPv6 static leases", args[0])
|
|
|
- } else {
|
|
|
- log.Printf("Using redis server %s for DHCPv4 static leases", args[0])
|
|
|
- }
|
|
|
-
|
|
|
- // Initialize Redis Pool
|
|
|
- pool = &redis.Pool{
|
|
|
- MaxIdle: 10,
|
|
|
- IdleTimeout: 240 * time.Second,
|
|
|
- Dial: func() (redis.Conn, error) {
|
|
|
- return redis.Dial("tcp", args[0])
|
|
|
- },
|
|
|
- }
|
|
|
-
|
|
|
- return Handler6, Handler4, nil
|
|
|
-}
|