File: funcs.go

package info (click to toggle)
golang-github-malfunkt-iprange 0.9.0-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, sid
  • size: 116 kB
  • sloc: yacc: 86; makefile: 2
file content (92 lines) | stat: -rw-r--r-- 1,674 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package iprange

import (
	"encoding/binary"
	"net"
	"sort"
)

func streamRange(lower, upper net.IP) chan net.IP {
	ipchan := make(chan net.IP, 1)

	rangeMask := net.IP([]byte{
		upper[0] - lower[0],
		upper[1] - lower[1],
		upper[2] - lower[2],
		upper[3] - lower[3],
	})

	go func() {
		defer close(ipchan)

		lower32 := binary.BigEndian.Uint32([]byte(lower))
		upper32 := binary.BigEndian.Uint32([]byte(upper))
		diff := upper32 - lower32

		if diff < 0 {
			panic("Lower address is actually higher than upper address.")
		}

		mask := net.IP([]byte{0, 0, 0, 0})

		for {
			ipchan <- net.IP([]byte{
				lower[0] + mask[0],
				lower[1] + mask[1],
				lower[2] + mask[2],
				lower[3] + mask[3],
			})

			if mask.Equal(rangeMask) {
				break
			}

			for i := 3; i >= 0; i-- {
				if rangeMask[i] > 0 {
					if mask[i] < rangeMask[i] {
						mask[i] = mask[i] + 1
						break
					} else {
						mask[i] = mask[i] % rangeMask[i]
						if i < 1 {
							break
						}
					}
				}
			}
		}

	}()

	return ipchan
}

// Expand expands an address with a mask taken from a stream
func (r *AddressRange) Expand() []net.IP {
	ips := []net.IP{}
	for ip := range streamRange(r.Min, r.Max) {
		ips = append(ips, ip)
	}
	return ips
}

// Expand expands and normalizes a set of parsed target specifications
func (l AddressRangeList) Expand() []net.IP {
	var res []net.IP
	for i := range l {
		res = append(res, l[i].Expand()...)
	}
	return normalize(res)
}

func normalize(src []net.IP) []net.IP {
	sort.Sort(asc(src))
	dst := make([]net.IP, 1, len(src))
	dst[0] = src[0]
	for i := range src {
		if !dst[len(dst)-1].Equal(src[i]) {
			dst = append(dst, src[i])
		}
	}
	return dst
}