@@ -367,7 +367,7 @@ func IsNetworkAddressV4(value string) error {
367367}
368368
369369// IsNetworkAddressCIDRV4 validates an IPv4 address string in CIDR format.
370- func IsNetworkAddressCIDRV4 (value string ) error {
370+ func IsNetworkAddressCIDRV4 (value string , allowSingle bool ) error {
371371 ip , subnet , err := net .ParseCIDR (value )
372372 if err != nil {
373373 return err
@@ -377,6 +377,12 @@ func IsNetworkAddressCIDRV4(value string) error {
377377 return fmt .Errorf ("Not an IPv4 address %q" , value )
378378 }
379379
380+ subnetSize , _ := subnet .Mask .Size ()
381+ if allowSingle && subnetSize == 32 {
382+ // Single addresses are allowed through.
383+ return nil
384+ }
385+
380386 if ip .String () == subnet .IP .String () {
381387 return fmt .Errorf ("Not a usable IPv4 address %q" , value )
382388 }
@@ -430,7 +436,7 @@ func IsNetworkAddressV6(value string) error {
430436}
431437
432438// IsNetworkAddressCIDRV6 validates an IPv6 address string in CIDR format.
433- func IsNetworkAddressCIDRV6 (value string ) error {
439+ func IsNetworkAddressCIDRV6 (value string , allowSingle bool ) error {
434440 ip , subnet , err := net .ParseCIDR (value )
435441 if err != nil {
436442 return err
@@ -440,6 +446,12 @@ func IsNetworkAddressCIDRV6(value string) error {
440446 return fmt .Errorf ("Not an IPv6 address %q" , value )
441447 }
442448
449+ subnetSize , _ := subnet .Mask .Size ()
450+ if allowSingle && subnetSize == 128 {
451+ // Single addresses are allowed through.
452+ return nil
453+ }
454+
443455 if ip .String () == subnet .IP .String () {
444456 return fmt .Errorf ("Not a usable IPv6 address %q" , value )
445457 }
0 commit comments