this is cool and all but the tables don't render properly
This commit is contained in:
@@ -4,6 +4,7 @@ import "errors"
|
||||
|
||||
var (
|
||||
ErrBadBoundary error = errors.New("subnet does not align on bit boundary")
|
||||
ErrBadNumHosts error = errors.New("bad number of hosts; cannot split into prefix exactly")
|
||||
ErrBadPrefix error = errors.New("prefix is invalid")
|
||||
ErrBadPrefixLen error = errors.New("prefix length exceeds maximum possible for prefix's inet family")
|
||||
ErrBadSplitter error = errors.New("invalid or unknown splitter when containing")
|
||||
|
||||
@@ -4,11 +4,12 @@ import (
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"github.com/goccy/go-yaml"
|
||||
"go4.org/netipx"
|
||||
"net"
|
||||
"net/netip"
|
||||
"strings"
|
||||
|
||||
"github.com/goccy/go-yaml"
|
||||
"go4.org/netipx"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -96,9 +97,9 @@ Set as 0 or `segSep` to an empty string to do no string segmentation.
|
||||
func AddrFmt(ip netip.Addr, f, sep, segSep string, every, everySeg uint) (s string) {
|
||||
|
||||
var numSegs int
|
||||
var doSep bool = every > 0
|
||||
var fs string = "%" + f
|
||||
var sb *strings.Builder = new(strings.Builder)
|
||||
var doSep = every > 0
|
||||
var fs = "%" + f
|
||||
var sb = new(strings.Builder)
|
||||
|
||||
if ip.IsUnspecified() || !ip.IsValid() {
|
||||
return
|
||||
@@ -152,7 +153,7 @@ func AddrInvert(ip netip.Addr) (inverted netip.Addr) {
|
||||
func Contain(origPfx *netip.Prefix, nets []*netip.Prefix, remaining *netipx.IPSet, splitter NetSplitter) (s *StructuredResults, err error) {
|
||||
|
||||
var rem []netip.Prefix
|
||||
var sr StructuredResults = StructuredResults{
|
||||
var sr = StructuredResults{
|
||||
Original: origPfx,
|
||||
}
|
||||
|
||||
@@ -243,9 +244,9 @@ Its parameters hold the same significance as in AddrFmt.
|
||||
func MaskFmt(mask net.IPMask, f, sep, segSep string, every, everySeg uint) (s string) {
|
||||
|
||||
var numSegs int
|
||||
var doSep bool = every > 0
|
||||
var fs string = "%" + f
|
||||
var sb *strings.Builder = new(strings.Builder)
|
||||
var doSep = every > 0
|
||||
var fs = "%" + f
|
||||
var sb = new(strings.Builder)
|
||||
|
||||
if mask == nil || len(mask) == 0 {
|
||||
return
|
||||
|
||||
@@ -1,14 +1,58 @@
|
||||
package netsplit
|
||||
|
||||
import (
|
||||
"go4.org/netipx"
|
||||
"net/netip"
|
||||
|
||||
"go4.org/netipx"
|
||||
)
|
||||
|
||||
// Split splits the network defined in a CIDRSplitter alongside its configuration and performs the subnetting.
|
||||
/*
|
||||
Split splits the network defined in a CIDRSplitter alongside its configuration and performs the subnetting.
|
||||
This strategy attempts to split a network into subnets of a single uniform explicit size.
|
||||
*/
|
||||
func (c *CIDRSplitter) Split() (nets []*netip.Prefix, remaining *netipx.IPSet, err error) {
|
||||
|
||||
// TODO
|
||||
var ok bool
|
||||
var base netip.Prefix
|
||||
var sub netip.Prefix
|
||||
var subPtr *netip.Prefix
|
||||
var ipsb *netipx.IPSetBuilder = new(netipx.IPSetBuilder)
|
||||
|
||||
if c == nil || c.PrefixLength == 0 || c.BaseSplitter == nil || c.network == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if base, ok = netipx.FromStdIPNet(c.network); !ok {
|
||||
err = ErrBadBoundary
|
||||
return
|
||||
}
|
||||
if !base.IsValid() {
|
||||
err = ErrBadBoundary
|
||||
return
|
||||
}
|
||||
|
||||
if c.PrefixLength > uint8(base.Bits()) {
|
||||
err = ErrBigPrefix
|
||||
return
|
||||
}
|
||||
|
||||
ipsb.AddPrefix(base)
|
||||
if remaining, err = ipsb.IPSet(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
if sub, remaining, ok = remaining.RemoveFreePrefix(c.PrefixLength); !ok {
|
||||
if !sub.IsValid() {
|
||||
// No error; it's literally impossible since we network on boundaries.
|
||||
// We just hit the end of the prefix.
|
||||
break
|
||||
}
|
||||
subPtr = new(netip.Prefix)
|
||||
*subPtr = sub
|
||||
nets = append(nets, subPtr)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,14 +1,68 @@
|
||||
package netsplit
|
||||
|
||||
import (
|
||||
"go4.org/netipx"
|
||||
`math/big`
|
||||
`net`
|
||||
"net/netip"
|
||||
|
||||
`github.com/projectdiscovery/mapcidr`
|
||||
"go4.org/netipx"
|
||||
)
|
||||
|
||||
// Split splits the network defined in a HostSplitter alongside its configuration and performs the subnetting.
|
||||
/*
|
||||
Split splits the network defined in a HostSplitter alongside its configuration and performs the subnetting.
|
||||
This strategy attempts to split the network into subnets of equal number of hosts.
|
||||
|
||||
remaining may or may not be nil depending on if the number of hosts can fit cleanly within equal network sizes on boundaries.
|
||||
|
||||
An ErrBadNumHosts will be returned if the number of hosts does not match the *addressable* range in a prefix.
|
||||
*/
|
||||
func (h *HostSplitter) Split() (nets []*netip.Prefix, remaining *netipx.IPSet, err error) {
|
||||
|
||||
// TODO
|
||||
var tgt *big.Int
|
||||
var hosts *big.Int
|
||||
var sub netip.Prefix
|
||||
var subPtr *netip.Prefix
|
||||
var split []*net.IPNet
|
||||
var ipsb *netipx.IPSetBuilder = new(netipx.IPSetBuilder)
|
||||
|
||||
if h == nil || h.NumberHosts == 0 || h.BaseSplitter == nil || h.network == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if split, err = mapcidr.SplitIPNetByNumber(h.network, int(h.NumberHosts)); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
tgt = big.NewInt(0)
|
||||
tgt.SetUint64(uint64(h.NumberHosts))
|
||||
|
||||
nets = make([]*netip.Prefix, len(split))
|
||||
for idx, n := range split {
|
||||
sub, _ = netipx.FromStdIPNet(n)
|
||||
hosts = mapcidr.CountIPsInCIDR(false, false, n)
|
||||
if hosts == nil || tgt.Cmp(hosts) != 0 {
|
||||
err = &SplitErr{
|
||||
Wrapped: ErrBadNumHosts,
|
||||
Nets: nets,
|
||||
Remaining: remaining,
|
||||
LastSubnet: &sub,
|
||||
RequestedPrefixLen: uint8(sub.Bits()),
|
||||
}
|
||||
ipsb.AddPrefix(sub)
|
||||
} else {
|
||||
subPtr = new(netip.Prefix)
|
||||
*subPtr = sub
|
||||
nets = append(nets, subPtr)
|
||||
}
|
||||
|
||||
nets[idx] = new(netip.Prefix)
|
||||
*nets[idx] = sub
|
||||
}
|
||||
|
||||
if remaining, err = ipsb.IPSet(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package netsplit
|
||||
|
||||
import (
|
||||
"go4.org/netipx"
|
||||
"net/netip"
|
||||
|
||||
"go4.org/netipx"
|
||||
)
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,14 +1,106 @@
|
||||
package netsplit
|
||||
|
||||
import (
|
||||
"go4.org/netipx"
|
||||
`net`
|
||||
"net/netip"
|
||||
|
||||
`github.com/projectdiscovery/mapcidr`
|
||||
"go4.org/netipx"
|
||||
)
|
||||
|
||||
// Split splits the network defined in a SubnetSplitter alongside its configuration and performs the subnetting.
|
||||
/*
|
||||
Split splits the network defined in a SubnetSplitter alongside its configuration and performs the subnetting.
|
||||
This strategy allows for splitting a network into exactly evenly sized specified number of subnets.
|
||||
|
||||
remaining may or may not be nil depending on if the specified number of subnets fit cleanly into the network boundaries.
|
||||
|
||||
An ErrNoNetSpace error will be returned if subnetting size exhaustion occurs before the specified number of subnets is reached
|
||||
(but nets will be populated and remaining will contain any left over subnets).
|
||||
*/
|
||||
func (s *SubnetSplitter) Split() (nets []*netip.Prefix, remaining *netipx.IPSet, err error) {
|
||||
|
||||
// TODO
|
||||
var ok bool
|
||||
var pfxLen int
|
||||
var base netip.Prefix
|
||||
var sub netip.Prefix
|
||||
var subPtr *netip.Prefix
|
||||
var split []*net.IPNet
|
||||
var ipsb *netipx.IPSetBuilder = new(netipx.IPSetBuilder)
|
||||
|
||||
if s == nil || s.BaseSplitter == nil || s.network == nil || s.NumberSubnets == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if base, ok = netipx.FromStdIPNet(s.network); !ok {
|
||||
err = ErrBadBoundary
|
||||
return
|
||||
}
|
||||
if !base.IsValid() {
|
||||
err = ErrBadBoundary
|
||||
return
|
||||
}
|
||||
|
||||
if split, err = mapcidr.SplitIPNetIntoN(s.network, int(s.NumberSubnets)); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, n := range split {
|
||||
if sub, ok = netipx.FromStdIPNet(n); !ok {
|
||||
// We bail early on this error.
|
||||
err = &SplitErr{
|
||||
Wrapped: ErrBadBoundary,
|
||||
Nets: nets,
|
||||
Remaining: remaining,
|
||||
LastSubnet: subPtr,
|
||||
RequestedPrefixLen: 0,
|
||||
}
|
||||
err = ErrBadBoundary
|
||||
return
|
||||
}
|
||||
if sub.String() == base.String() {
|
||||
continue
|
||||
}
|
||||
if pfxLen == 0 {
|
||||
pfxLen = sub.Bits()
|
||||
if nets == nil {
|
||||
nets = make([]*netip.Prefix, 0)
|
||||
}
|
||||
subPtr = new(netip.Prefix)
|
||||
*subPtr = sub
|
||||
nets = append(nets, subPtr)
|
||||
} else {
|
||||
if sub.Bits() != pfxLen {
|
||||
if err == nil {
|
||||
// Return this err but don't return early; wait for the populate.
|
||||
err = &SplitErr{
|
||||
Wrapped: ErrNoNetSpace,
|
||||
Nets: nets,
|
||||
Remaining: remaining,
|
||||
LastSubnet: subPtr,
|
||||
RequestedPrefixLen: uint8(pfxLen),
|
||||
}
|
||||
}
|
||||
ipsb.AddPrefix(sub)
|
||||
} else {
|
||||
subPtr = new(netip.Prefix)
|
||||
*subPtr = sub
|
||||
nets = append(nets, subPtr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if remaining, err = ipsb.IPSet(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if len(nets) < int(s.NumberSubnets) {
|
||||
err = &SplitErr{
|
||||
Wrapped: ErrNoNetSpace,
|
||||
Nets: nets,
|
||||
Remaining: remaining,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
package netsplit
|
||||
|
||||
import (
|
||||
"go4.org/netipx"
|
||||
"net/netip"
|
||||
"sort"
|
||||
|
||||
"go4.org/netipx"
|
||||
)
|
||||
|
||||
// Split splits the network defined in a VLSMSplitter alongside its configuration and performs the subnetting.
|
||||
/*
|
||||
Split splits the network defined in a VLSMSplitter alongside its configuration and performs the subnetting.
|
||||
This strategy allows for multiple subnets of differing sizes to be specified.
|
||||
|
||||
remaining may or may not be nil depending on if all desired subnet sizes fit cleanly into the network boundaries.
|
||||
*/
|
||||
func (v *VLSMSplitter) Split() (nets []*netip.Prefix, remaining *netipx.IPSet, err error) {
|
||||
|
||||
var ok bool
|
||||
@@ -15,7 +21,7 @@ func (v *VLSMSplitter) Split() (nets []*netip.Prefix, remaining *netipx.IPSet, e
|
||||
var base netip.Prefix
|
||||
var sub netip.Prefix
|
||||
var subPtr *netip.Prefix
|
||||
var ipsb *netipx.IPSetBuilder = new(netipx.IPSetBuilder)
|
||||
var ipsb = new(netipx.IPSetBuilder)
|
||||
|
||||
if err = ValidateSizes(v.network, v.PrefixLengths...); err != nil {
|
||||
return
|
||||
|
||||
3
netsplit/init.go
Normal file
3
netsplit/init.go
Normal file
@@ -0,0 +1,3 @@
|
||||
package netsplit
|
||||
|
||||
// TODO?
|
||||
@@ -2,9 +2,10 @@ package netsplit
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"go4.org/netipx"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"go4.org/netipx"
|
||||
)
|
||||
|
||||
// SplitErr is used to wrap an error with context surrounding when/how that error was encountered.
|
||||
@@ -48,7 +49,9 @@ It attempts to evenly distribute addresses amoungs subnets.
|
||||
*/
|
||||
type HostSplitter struct {
|
||||
// NumberHosts is the number of hosts to be placed in each subnet to split out.
|
||||
NumberHosts uint `json:"hosts" xml:"hosts,attr" yaml:"Number of Hosts Per Subnet"`
|
||||
NumberHosts uint `json:"hosts" xml:"hosts,attr" yaml:"Number of Hosts Per Subnet"`
|
||||
// Strict, if true, will return an error from Split if the network cannot split into subnets of NumberHosts-addressable networks exactly.
|
||||
Strict bool `json:"strict" xml:"strict,attr,omitempty" yaml:"Strictly Equal Hosts Per Subnet"`
|
||||
*BaseSplitter `json:"net" xml:"net,omitempty" yaml:"network,omitempty"`
|
||||
}
|
||||
|
||||
@@ -59,6 +62,8 @@ as cleanly as poossible.
|
||||
type SubnetSplitter struct {
|
||||
// NumberSubnets indicates the number of subnets to split the network into.
|
||||
NumberSubnets uint `json:"nets" xml:"nets,attr" yaml:"Number of Target Subnets"`
|
||||
// Strict, if true, will return an error from Split if the network sizes cannot split into equally-sized networks.
|
||||
Strict bool `json:"strict" xml:"strict,attr,omitempty" yaml:"Strictly Equal Subnet Sizes"`
|
||||
*BaseSplitter `json:"net" xml:"net,omitempty" yaml:"network,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user