package host import ( "fmt" "lux/proto" "net" ) type LuxOptionType uint const ( LuxOptionTypeWAN = 0 LuxOptionTypeWAN6 = 1 ) type LuxOption interface { Read(rd *proto.LuxBuffer) error Write(wd *proto.LuxBuffer) Type() LuxOptionType } type LuxOptionWAN struct { Addr4 net.IP } func (opt *LuxOptionWAN) Read(rd *proto.LuxBuffer) error { octets, err := rd.ReadNext(4) if err != nil { return err } opt.Addr4 = net.IP(octets) return nil } func (opt *LuxOptionWAN) Write(wd *proto.LuxBuffer) { wd.WriteBytes(opt.Addr4.To4()) } func (*LuxOptionWAN) Type() LuxOptionType { return LuxOptionTypeWAN } type LuxOptionWAN6 struct { Addr6 net.IP } func (opt *LuxOptionWAN6) Read(rd *proto.LuxBuffer) error { octets, err := rd.ReadNext(16) if err != nil { return err } opt.Addr6 = net.IP(octets) return nil } func (opt *LuxOptionWAN6) Write(wd *proto.LuxBuffer) { wd.WriteBytes(opt.Addr6.To16()) } func (*LuxOptionWAN6) Type() LuxOptionType { return LuxOptionTypeWAN6 } func ReadLuxOption(rd *proto.LuxBuffer) (LuxOption, error) { var err error optVal, err := rd.ReadUint16() if err != nil { return nil, err } switch LuxOptionType(optVal) { case LuxOptionTypeWAN: opt := &LuxOptionWAN{} err = opt.Read(rd) return opt, err case LuxOptionTypeWAN6: opt := &LuxOptionWAN6{} err = opt.Read(rd) return opt, err default: return nil, fmt.Errorf("unknown option %d", optVal) } } func WriteLuxOption(wd *proto.LuxBuffer, opt LuxOption) { wd.WriteUint16(uint16(opt.Type())) opt.Write(wd) }