plugin.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package clientport
  2. import (
  3. "errors"
  4. "fmt"
  5. "net"
  6. "strings"
  7. "github.com/coredhcp/coredhcp/handler"
  8. "github.com/coredhcp/coredhcp/logger"
  9. "github.com/coredhcp/coredhcp/plugins"
  10. "github.com/insomniacslk/dhcp/dhcpv4"
  11. "github.com/insomniacslk/dhcp/dhcpv6"
  12. "github.com/insomniacslk/dhcp/iana"
  13. )
  14. var log = logger.GetLogger()
  15. func init() {
  16. plugins.RegisterPlugin("server_id", setupServerID6, setupServerID4)
  17. }
  18. // V6ServerID is the DUID of the v6 server
  19. var V6ServerID *dhcpv6.Duid
  20. // Handler6 handles DHCPv6 packets for the file plugin
  21. func Handler6(req, resp dhcpv6.DHCPv6) (dhcpv6.DHCPv6, bool) {
  22. if V6ServerID == nil {
  23. return resp, false
  24. }
  25. if resp == nil {
  26. var (
  27. tmp dhcpv6.DHCPv6
  28. err error
  29. )
  30. switch req.Type() {
  31. case dhcpv6.MessageTypeSolicit:
  32. tmp, err = dhcpv6.NewAdvertiseFromSolicit(req)
  33. case dhcpv6.MessageTypeRequest, dhcpv6.MessageTypeConfirm, dhcpv6.MessageTypeRenew,
  34. dhcpv6.MessageTypeRebind, dhcpv6.MessageTypeRelease, dhcpv6.MessageTypeInformationRequest:
  35. tmp, err = dhcpv6.NewReplyFromDHCPv6Message(req)
  36. default:
  37. err = fmt.Errorf("plugins/server_id: message type %d not supported", req.Type())
  38. }
  39. if err != nil {
  40. log.Printf("plugins/server_id: NewReplyFromDHCPv6Message failed: %v", err)
  41. return resp, false
  42. }
  43. resp = tmp
  44. }
  45. resp = dhcpv6.WithServerID(*V6ServerID)(resp)
  46. return resp, false
  47. }
  48. // Handler4 handles DHCPv4 packets for the file plugin
  49. func Handler4(req, resp *dhcpv4.DHCPv4) (*dhcpv4.DHCPv4, bool) {
  50. // do nothing
  51. return resp, false
  52. }
  53. func setupServerID4(args ...string) (handler.Handler4, error) {
  54. // TODO implement this function
  55. return nil, errors.New("plugins/server_id: not implemented for DHCPv4")
  56. }
  57. func setupServerID6(args ...string) (handler.Handler6, error) {
  58. log.Print("plugins/server_id: loading `server_id` plugin")
  59. if len(args) < 2 {
  60. return nil, errors.New("plugins/server_id: need a DUID type and value")
  61. }
  62. duidType := args[0]
  63. if duidType == "" {
  64. return nil, errors.New("plugins/server_id: got empty DUID type")
  65. }
  66. duidValue := args[1]
  67. if duidValue == "" {
  68. return nil, errors.New("plugins/server_id: got empty DUID value")
  69. }
  70. duidType = strings.ToLower(duidType)
  71. hwaddr, err := net.ParseMAC(duidValue)
  72. if err != nil {
  73. return nil, err
  74. }
  75. switch duidType {
  76. case "ll", "duid-ll", "duid_ll":
  77. V6ServerID = &dhcpv6.Duid{
  78. Type: dhcpv6.DUID_LL,
  79. // sorry, only ethernet for now
  80. HwType: iana.HwTypeEthernet,
  81. LinkLayerAddr: hwaddr,
  82. }
  83. case "llt", "duid-llt", "duid_llt":
  84. V6ServerID = &dhcpv6.Duid{
  85. Type: dhcpv6.DUID_LLT,
  86. // sorry, zero-time for now
  87. Time: 0,
  88. // sorry, only ethernet for now
  89. HwType: iana.HwTypeEthernet,
  90. LinkLayerAddr: hwaddr,
  91. }
  92. case "en", "uuid":
  93. return nil, errors.New("EN/UUID DUID type not supported yet")
  94. default:
  95. return nil, errors.New("Opaque DUID type not supported yet")
  96. }
  97. log.Printf("plugins/server_id: using %s %s", duidType, duidValue)
  98. return Handler6, nil
  99. }