Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
# cider

`cider` is a CLI tool for assisting with common IP-related tasks.
28 changes: 14 additions & 14 deletions internal/cidr/cidr_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ func ipToDecimal(ip string) int {
parts := strings.Split(ip, ".")

base := 10
octet1 := must(strconv.ParseInt(parts[0], base, INT_SIZE))
octet2 := must(strconv.ParseInt(parts[1], base, INT_SIZE))
octet3 := must(strconv.ParseInt(parts[2], base, INT_SIZE))
octet4 := must(strconv.ParseInt(parts[3], base, INT_SIZE))
octet1 := must(strconv.ParseUint(parts[0], base, INT_SIZE))
octet2 := must(strconv.ParseUint(parts[1], base, INT_SIZE))
octet3 := must(strconv.ParseUint(parts[2], base, INT_SIZE))
octet4 := must(strconv.ParseUint(parts[3], base, INT_SIZE))

return int((octet1 * 16777216) + (octet2 * 65536) + (octet3 * 256) + octet4)
}
Expand All @@ -82,8 +82,8 @@ func (b *CIDRBlock) NetworkPortionBinary() string {
}

func toBin(s string) string {
asInt := must(strconv.ParseInt(s, 10, INT_SIZE))
asBinaryString := strconv.FormatInt(asInt, 2)
asInt := must(strconv.ParseUint(s, 10, INT_SIZE))
asBinaryString := strconv.FormatUint(asInt, 2)
paddedBynaryString := utils.PadLeft(asBinaryString, '0', 8)
return paddedBynaryString
}
Expand Down Expand Up @@ -120,9 +120,9 @@ func (b *CIDRBlock) StartAddressOfNextBlock() string {
octets = list.Map(octets, toBin)
binStr := strings.Join(octets, "")

next := must(strconv.ParseInt(binStr, 2, INT_SIZE)) + 1
next := must(strconv.ParseUint(binStr, 2, INT_SIZE)) + 1

asBinaryString := strconv.FormatInt(next, 2)
asBinaryString := strconv.FormatUint(next, 2)
asBinaryString = utils.PadLeft(asBinaryString, '0', 32)

octetsInt := stringToOctets(asBinaryString)
Expand Down Expand Up @@ -151,14 +151,14 @@ func (b *CIDRBlock) BroadcastAddress() string {
return fmt.Sprintf("%v.%v.%v.%v", octets[0], octets[1], octets[2], octets[3])
}

func stringToOctets(ipString string) []int64 {
octets := make([]int64, 4)
func stringToOctets(ipString string) []uint64 {
octets := make([]uint64, 4)

base := 2
octets[0] = must(strconv.ParseInt(ipString[0:8], base, INT_SIZE))
octets[1] = must(strconv.ParseInt(ipString[8:16], base, INT_SIZE))
octets[2] = must(strconv.ParseInt(ipString[16:24], base, INT_SIZE))
octets[3] = must(strconv.ParseInt(ipString[24:32], base, INT_SIZE))
octets[0] = must(strconv.ParseUint(ipString[0:8], base, INT_SIZE))
octets[1] = must(strconv.ParseUint(ipString[8:16], base, INT_SIZE))
octets[2] = must(strconv.ParseUint(ipString[16:24], base, INT_SIZE))
octets[3] = must(strconv.ParseUint(ipString[24:32], base, INT_SIZE))

return octets
}
Expand Down
11 changes: 9 additions & 2 deletions internal/cidr/cidr_block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ func Test_NetworkPortionBinary(t *testing.T) {
input *cidr.CIDRBlock
expected string
}{
"/0": {input: cidr.NewBlock("10.0.0.0/0"), expected: "00001010.00000000.00000000.00000000"},
"10.0.0.0/8": {input: cidr.NewBlock("10.0.0.0/8"), expected: "00001010.00000000.00000000.00000000"},
"172.16.0.0/12": {input: cidr.NewBlock("172.16.0.0/12"), expected: "10101100.00010000.00000000.00000000"},
"192.168.0.0/16": {input: cidr.NewBlock("192.168.0.0/16"), expected: "11000000.10101000.00000000.00000000"},
}

for name, test := range tests {
Expand Down Expand Up @@ -206,7 +208,12 @@ func Test_StartAddressOfNextBlock(t *testing.T) {
input *cidr.CIDRBlock
expected string
}{
"/17": {input: cidr.NewBlock("10.0.0.0/17"), expected: "10.0.128.0"},
"10.0.0.0/8": {input: cidr.NewBlock("10.0.0.0/8"), expected: "11.0.0.0"},
"127.0.0.0/8": {input: cidr.NewBlock("127.0.0.0/8"), expected: "128.0.0.0"},
"169.254.0.0/16": {input: cidr.NewBlock("169.254.0.0/16"), expected: "169.255.0.0"},
"172.16.0.0/12": {input: cidr.NewBlock("172.16.0.0/12"), expected: "172.32.0.0"},
"192.0.2.0/24": {input: cidr.NewBlock("192.0.2.0/24"), expected: "192.0.3.0"},
"192.168.0.0/16": {input: cidr.NewBlock("192.168.0.0/16"), expected: "192.169.0.0"},
}

for name, test := range tests {
Expand Down
1 change: 1 addition & 0 deletions internal/commands/in/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func (h *handler) Handle(args []string) error {
}

ip := args[0]

ranges := list.Map(args[1:], func(i string) *cidr.CIDRBlock {
return cidr.NewBlock(i)
})
Expand Down
17 changes: 8 additions & 9 deletions internal/commands/info/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func New() *handler {
}

type pair struct {
a, b string
item1, item2 string
}

func (h *handler) Handle(args []string) error {
Expand All @@ -28,12 +28,11 @@ func (h *handler) Handle(args []string) error {
block := cidr.NewBlock(ip)

entries := []pair{
{a: "Address range", b: fmt.Sprintf("%s - %s", block.NetworkAddress(), block.BroadcastAddress())},
{a: "Start of next block", b: block.StartAddressOfNextBlock()},
{a: "Cidr", b: fmt.Sprintf("/%v", block.HostPortion)},
{a: "Subnet mask", b: block.SubnetMask()},
{a: "Addresses", b: fmt.Sprintf("%v", block.AvailableHosts())},
{a: "Azure addresses", b: block.AvailableAzureHosts()},
{item1: "Address range", item2: fmt.Sprintf("%s - %s", block.NetworkAddress(), block.BroadcastAddress())},
{item1: "Start of next block", item2: block.StartAddressOfNextBlock()},
{item1: "Mask", item2: fmt.Sprintf("%s (%s)", fmt.Sprintf("/%v", block.HostPortion), block.SubnetMask())},
{item1: "Addresses", item2: fmt.Sprintf("%v", block.AvailableHosts())},
{item1: "Azure addresses", item2: block.AvailableAzureHosts()},
}

printOutput(entries)
Expand All @@ -44,14 +43,14 @@ func (h *handler) Handle(args []string) error {
func printOutput(entries []pair) {
keys := []string{}
for _, pair := range entries {
keys = append(keys, pair.a)
keys = append(keys, pair.item1)
}

longestTitle := list.Fold(keys, 0, func(title string, acc int) int {
return int(math.Max(float64(acc), float64(len(title))))
})

for _, pair := range entries {
fmt.Printf("%s : %v\n", utils.PadRight(pair.a, ' ', longestTitle), pair.b)
fmt.Printf("%s : %v\n", utils.PadRight(pair.item1, ' ', longestTitle), pair.item2)
}
}
24 changes: 12 additions & 12 deletions internal/commands/ranges/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,45 +21,45 @@ func New() *handler {
func (*handler) Handle(arg string) error {
// no args
if arg == "" {
table := calculateAllCIDRBlocks()
table := calculateAllCidrBlocks()

return printCIDRBlocks(table)
return printCidrBlocks(table)
}

// argument was given - try to parse it
// argument was given. Try to parse it
hostPortion, err := strconv.ParseInt(arg, 10, INT_SIZE)

if err != nil {
return fmt.Errorf("%s is not a valid integer", arg)
}

if hostPortion < 0 || hostPortion > INT_SIZE {
return fmt.Errorf("%v is not a valid size - must be between 0 and 32", hostPortion)
return fmt.Errorf("%v is not a valid size - must be between 0 and %d", hostPortion, INT_SIZE)
}

block := calculateCIDRBlock(int(hostPortion))
block := defaultCidrBlockFromHostPortion(int(hostPortion))

table := []*cidr.CIDRBlock{block}
blocks := []*cidr.CIDRBlock{block}

return printCIDRBlocks(table)
return printCidrBlocks(blocks)
}

func calculateAllCIDRBlocks() []*cidr.CIDRBlock {
func calculateAllCidrBlocks() []*cidr.CIDRBlock {
blocks := []*cidr.CIDRBlock{}
for i := 0; i < INT_SIZE+1; i++ {
block := calculateCIDRBlock(i)
for i := range INT_SIZE + 1 {
block := defaultCidrBlockFromHostPortion(i)

blocks = append(blocks, block)
}

return blocks
}

func calculateCIDRBlock(hostPortion int) *cidr.CIDRBlock {
func defaultCidrBlockFromHostPortion(hostPortion int) *cidr.CIDRBlock {
return cidr.NewBlock(fmt.Sprintf("10.0.0.0/%v", hostPortion))
}

func printCIDRBlocks(blocks []*cidr.CIDRBlock) error {
func printCidrBlocks(blocks []*cidr.CIDRBlock) error {
w := tabwriter.NewWriter(os.Stdout, 2, 4, 1, ' ', 0)

fmt.Fprint(w, "Cidr\tSubnet mask\tAddresses\tAzure addresses\n")
Expand Down
7 changes: 6 additions & 1 deletion internal/list/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ func FlatMap[T, K any](v []T, f func(T) []K) []K {
}

func Contains[T any](v []T, f func(T) bool) bool {
return len(Filter(v, f)) > 0
for _, i := range v {
if f(i) {
return true
}
}
return false
}

func All[T any](v []T, f func(T) bool) bool {
Expand Down