this is cool and all but the tables don't render properly

This commit is contained in:
2025-02-01 23:15:54 -05:00
parent b09cb83017
commit 3a7ed5973b
28 changed files with 1917 additions and 88 deletions

View File

@@ -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")

View File

@@ -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

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -1,8 +1,9 @@
package netsplit
import (
"go4.org/netipx"
"net/netip"
"go4.org/netipx"
)
/*

View File

@@ -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
}

View File

@@ -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
View File

@@ -0,0 +1,3 @@
package netsplit
// TODO?

View File

@@ -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"`
}