github.com/pwn-term/docker@v0.0.0-20210616085119-6e977cce2565/libnetwork/driverapi/ipamdata.go (about) 1 package driverapi 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net" 7 8 "github.com/docker/libnetwork/types" 9 ) 10 11 // MarshalJSON encodes IPAMData into json message 12 func (i *IPAMData) MarshalJSON() ([]byte, error) { 13 m := map[string]interface{}{} 14 m["AddressSpace"] = i.AddressSpace 15 if i.Pool != nil { 16 m["Pool"] = i.Pool.String() 17 } 18 if i.Gateway != nil { 19 m["Gateway"] = i.Gateway.String() 20 } 21 if i.AuxAddresses != nil { 22 am := make(map[string]string, len(i.AuxAddresses)) 23 for k, v := range i.AuxAddresses { 24 am[k] = v.String() 25 } 26 m["AuxAddresses"] = am 27 } 28 return json.Marshal(m) 29 } 30 31 // UnmarshalJSON decodes a json message into IPAMData 32 func (i *IPAMData) UnmarshalJSON(data []byte) error { 33 var ( 34 m map[string]interface{} 35 err error 36 ) 37 if err := json.Unmarshal(data, &m); err != nil { 38 return err 39 } 40 i.AddressSpace = m["AddressSpace"].(string) 41 if v, ok := m["Pool"]; ok { 42 if i.Pool, err = types.ParseCIDR(v.(string)); err != nil { 43 return err 44 } 45 } 46 if v, ok := m["Gateway"]; ok { 47 if i.Gateway, err = types.ParseCIDR(v.(string)); err != nil { 48 return err 49 } 50 } 51 if v, ok := m["AuxAddresses"]; ok { 52 b, _ := json.Marshal(v) 53 var am map[string]string 54 if err = json.Unmarshal(b, &am); err != nil { 55 return err 56 } 57 i.AuxAddresses = make(map[string]*net.IPNet, len(am)) 58 for k, v := range am { 59 if i.AuxAddresses[k], err = types.ParseCIDR(v); err != nil { 60 return err 61 } 62 } 63 } 64 return nil 65 } 66 67 // Validate checks whether the IPAMData structure contains congruent data 68 func (i *IPAMData) Validate() error { 69 var isV6 bool 70 if i.Pool == nil { 71 return types.BadRequestErrorf("invalid pool") 72 } 73 if i.Gateway == nil { 74 return types.BadRequestErrorf("invalid gateway address") 75 } 76 isV6 = i.IsV6() 77 if isV6 && i.Gateway.IP.To4() != nil || !isV6 && i.Gateway.IP.To4() == nil { 78 return types.BadRequestErrorf("incongruent ip versions for pool and gateway") 79 } 80 for k, sip := range i.AuxAddresses { 81 if isV6 && sip.IP.To4() != nil || !isV6 && sip.IP.To4() == nil { 82 return types.BadRequestErrorf("incongruent ip versions for pool and secondary ip address %s", k) 83 } 84 } 85 if !i.Pool.Contains(i.Gateway.IP) { 86 return types.BadRequestErrorf("invalid gateway address (%s) does not belong to the pool (%s)", i.Gateway, i.Pool) 87 } 88 for k, sip := range i.AuxAddresses { 89 if !i.Pool.Contains(sip.IP) { 90 return types.BadRequestErrorf("invalid secondary address %s (%s) does not belong to the pool (%s)", k, i.Gateway, i.Pool) 91 } 92 } 93 return nil 94 } 95 96 // IsV6 returns whether this is an IPv6 IPAMData structure 97 func (i *IPAMData) IsV6() bool { 98 return nil == i.Pool.IP.To4() 99 } 100 101 func (i *IPAMData) String() string { 102 return fmt.Sprintf("AddressSpace: %s\nPool: %v\nGateway: %v\nAddresses: %v", i.AddressSpace, i.Pool, i.Gateway, i.AuxAddresses) 103 }