Skip to content

Commit

Permalink
Move code to dedicated files
Browse files Browse the repository at this point in the history
  • Loading branch information
Themimitoof committed Aug 17, 2022
1 parent a5fcee6 commit 2f1a8e1
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 92 deletions.
95 changes: 3 additions & 92 deletions ipg.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@ package main

import (
"fmt"
"math/rand"
"net"
"os"
"strings"
"time"

"github.com/alecthomas/kong"
"github.com/c-robinson/iplib"
"github.com/fatih/color"
"github.com/themimitoof/ipg/src"
)

var cli struct {
Expand All @@ -24,92 +21,6 @@ var cli struct {
DNSTTL int `name:"ttl" short:"t" default:"86400" help:"TTL value for DNS returned DNS records."`
}

// Function stollen from c-robinson/iplib, method non-exposed by the lib ¯\_(ツ)_/¯
func Net6wildcard(n iplib.Net6) net.IPMask {
wc := make([]byte, len(n.Mask()))
for i, b := range n.Mask() {
wc[i] = 0xff - b
}
return wc
}

func RandomNumber(min int, max int) int {
rand.Seed(time.Now().UnixNano())
return rand.Intn(max-min) + min
}

// Generate a random IP address based on the given IP subnet.
func GenerateRandomIP(net iplib.Net6) net.IP {
finalIP := net.FirstAddress()

for idx, b := range net.Mask() {
if b == 0xff {
continue
} else if b != 0x0 {
randByte := byte(RandomNumber(0, 255))
wildCardByte := Net6wildcard(net)[idx]

finalIP[idx] = net.IP()[idx] + wildCardByte&randByte
} else {
finalIP[idx] = byte(RandomNumber(0, 255))
}
}

return finalIP
}

// Generate an IP address based on the hostname.
// The algorithm first tries with the complete hostname, if it does not work,
// it tries by removing vowels and iterate by removing character by character.
func GenerateIPFromHostname(net iplib.Net6, hostname string) net.IP {
finalIP := []byte(net.FirstAddress())
cidr, _ := net.Mask().Size()
availableBits := 128 - cidr
hostname = strings.Split(hostname, ".")[0]

if len(hostname)*8 > availableBits {
// Remove vowels
shrinkedHostname := []byte{}
for _, c := range hostname {
asVowel := false

for _, v := range "aiueo" {
if c == v {
asVowel = true
}
}

if !asVowel {
shrinkedHostname = append(shrinkedHostname, byte(c))
}
}

// In case it's not enough, shrink last character until it fits
for len(shrinkedHostname)*8 > availableBits {
shrinkedHostname = shrinkedHostname[0 : len(shrinkedHostname)-1]
}

hostname = string(shrinkedHostname)
}

for i, c := range hostname {
pos := len(finalIP) - len(hostname) + i
finalIP[pos] = byte(c)
}

return finalIP
}

// Generate a DNS record ready to be paste on a Bind compatible zone
func GenerateDNSRecord(ip string, ttl int, hostname string) string {
return fmt.Sprintf("%s\t%d\tIN\tAAAA\t%s", hostname, ttl, ip)
}

// Generate a ARPA record ready to be paste on a Bind compatible zone
func GenerateReverseDNSRecord(ip string, ttl int, hostname string) string {
return fmt.Sprintf("%s.\t%d\tIN\tPTR\t%s", ip, ttl, hostname)
}

func main() {
kong.Parse(
&cli,
Expand All @@ -136,9 +47,9 @@ func main() {
var generatedIp net.IP

if cli.Random {
generatedIp = GenerateRandomIP(ipNetwork)
generatedIp = src.GenerateRandomIP(ipNetwork)
} else {
generatedIp = GenerateIPFromHostname(ipNetwork, cli.Name)
generatedIp = src.GenerateIPFromHostname(ipNetwork, cli.Name)
}

var reverseIpAddr string = iplib.IPToARPA(generatedIp)
Expand Down
13 changes: 13 additions & 0 deletions src/dns.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package src

import "fmt"

// Generate a DNS record ready to be paste on a Bind compatible zone
func GenerateDNSRecord(ip string, ttl int, hostname string) string {
return fmt.Sprintf("%s\t%d\tIN\tAAAA\t%s", hostname, ttl, ip)
}

// Generate a ARPA record ready to be paste on a Bind compatible zone
func GenerateReverseDNSRecord(ip string, ttl int, hostname string) string {
return fmt.Sprintf("%s.\t%d\tIN\tPTR\t%s", ip, ttl, hostname)
}
79 changes: 79 additions & 0 deletions src/ip.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package src

import (
"net"
"strings"

"github.com/c-robinson/iplib"
)

// Function stollen from c-robinson/iplib, method non-exposed by the lib ¯\_(ツ)_/¯
func Net6wildcard(n iplib.Net6) net.IPMask {
wc := make([]byte, len(n.Mask()))
for i, b := range n.Mask() {
wc[i] = 0xff - b
}
return wc
}

// Generate a random IP address based on the given IP subnet.
func GenerateRandomIP(net iplib.Net6) net.IP {
finalIP := net.FirstAddress()

for idx, b := range net.Mask() {
if b == 0xff {
continue
} else if b != 0x0 {
randByte := byte(RandomNumber(0, 255))
wildCardByte := Net6wildcard(net)[idx]

finalIP[idx] = net.IP()[idx] + wildCardByte&randByte
} else {
finalIP[idx] = byte(RandomNumber(0, 255))
}
}

return finalIP
}

// Generate an IP address based on the hostname.
// The algorithm first tries with the complete hostname, if it does not work,
// it tries by removing vowels and iterate by removing character by character.
func GenerateIPFromHostname(net iplib.Net6, hostname string) net.IP {
finalIP := []byte(net.FirstAddress())
cidr, _ := net.Mask().Size()
availableBits := 128 - cidr
hostname = strings.Split(hostname, ".")[0]

if len(hostname)*8 > availableBits {
// Remove vowels
shrinkedHostname := []byte{}
for _, c := range hostname {
asVowel := false

for _, v := range "aiueo" {
if c == v {
asVowel = true
}
}

if !asVowel {
shrinkedHostname = append(shrinkedHostname, byte(c))
}
}

// In case it's not enough, shrink last character until it fits
for len(shrinkedHostname)*8 > availableBits {
shrinkedHostname = shrinkedHostname[0 : len(shrinkedHostname)-1]
}

hostname = string(shrinkedHostname)
}

for i, c := range hostname {
pos := len(finalIP) - len(hostname) + i
finalIP[pos] = byte(c)
}

return finalIP
}
11 changes: 11 additions & 0 deletions src/math.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package src

import (
"math/rand"
"time"
)

func RandomNumber(min int, max int) int {
rand.Seed(time.Now().UnixNano())
return rand.Intn(max-min) + min
}

0 comments on commit 2f1a8e1

Please sign in to comment.