plugin.go 2.8 KB

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